javauis/eswt_qt/org.eclipse.swt/Eclipse_SWT_PI/qt/library/graphics/qt/pixmap.cpp
changeset 80 d6dafc5d983f
parent 57 59b3b4473dc8
equal deleted inserted replaced
78:71ad690e91f5 80:d6dafc5d983f
    12 #include "gfxlog.h"
    12 #include "gfxlog.h"
    13 #include <memory>
    13 #include <memory>
    14 
    14 
    15 namespace Java { namespace GFX {
    15 namespace Java { namespace GFX {
    16 
    16 
    17 Pixmap::Pixmap() : mAlpha(-1), mHasMask(false)
    17 Pixmap::Pixmap() : ImageBase()
    18 {
    18     {
    19     GFX_LOG_FUNC_CALL();
    19     GFX_LOG_FUNC_CALL();
    20 }
    20     }
    21 
    21 
    22 Pixmap::~Pixmap()
    22 Pixmap::~Pixmap()
    23 {
    23     {
    24     GFX_LOG_FUNC_CALL();
    24     GFX_LOG_FUNC_CALL();
    25 }
    25     }
    26 
    26 
    27 void Pixmap::createBySize(int aWidth, int aHeight, int aFillColor, TImageFormat /*aFormat*/)
    27 void Pixmap::createBySize(int aWidth, int aHeight, int aFillColor, TImageFormat /*aFormat*/)
    28 {
    28     {
    29     GFX_LOG_FUNC_CALL();
    29     GFX_LOG_FUNC_CALL();
    30     Q_ASSERT(mPixmap.isNull());
    30     Q_ASSERT(mPixmap.isNull());
    31 
    31 
    32     // Pixmap's format is selected by the framework, thus it cannot be used here
    32     // Pixmap's format is selected by the framework, thus it cannot be used here
    33     mPixmap = QPixmap(aWidth, aHeight);
    33     mPixmap = QPixmap(aWidth, aHeight);
    34 
    34 
    35     // Check if creation was successful
    35     // Check if creation was successful
    36     if(mPixmap.isNull())
    36     if(mPixmap.isNull())
    37     {
    37         {
    38         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
    38         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
    39     }
    39         }
    40 
    40 
    41     // Finally fill with given fillColor, also clears the image mem area
    41     // Finally fill with given fillColor, also clears the image mem area
    42     // otherwise there might be some random coloured pixels in image
    42     // otherwise there might be some random coloured pixels in image
    43     QColor color;
    43     QColor color;
    44     color.setRgb(aFillColor);
    44     color.setRgb(aFillColor);
    45     mPixmap.fill(color);
    45     mPixmap.fill(color);
    46 }
    46     }
    47 
    47 
    48 void Pixmap::createFromQImage(const QImage& aImage)
    48 void Pixmap::createFromQImage(const QImage& aImage)
    49 {
    49     {
    50     GFX_LOG_FUNC_CALL();
    50     GFX_LOG_FUNC_CALL();
    51     Q_ASSERT(mPixmap.isNull());
    51     Q_ASSERT(mPixmap.isNull());
    52 
    52 
    53     // Convert to Pixmap
    53     // Convert to Pixmap
    54     mPixmap = QPixmap::fromImage(aImage);
    54     mPixmap = QPixmap::fromImage(aImage);
    55 
    55 
    56     // Validate allocation
    56     // Validate allocation
    57     if(mPixmap.isNull())
    57     if(mPixmap.isNull())
    58     {
    58         {
    59         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
    59         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
    60     }
    60         }
    61 }
    61     }
    62 
    62 
    63 void Pixmap::createFromQPixmap(const QPixmap& aPixmap)
    63 void Pixmap::createFromQPixmap(const QPixmap& aPixmap)
    64 {
    64     {
    65     GFX_LOG_FUNC_CALL();
    65     GFX_LOG_FUNC_CALL();
    66     Q_ASSERT(mPixmap.isNull());
    66     Q_ASSERT(mPixmap.isNull());
    67 
    67 
    68     mPixmap = QPixmap(aPixmap);
    68     mPixmap = QPixmap(aPixmap);
    69 
    69 
    70     // Validate allocation
    70     // Validate allocation
    71     if(mPixmap.isNull())
    71     if(mPixmap.isNull())
    72     {
    72         {
    73         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
    73         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
    74     }
    74         }
    75 }
    75     }
    76 
    76 
    77 void Pixmap::createFromImage(Image* aImage, int aX, int aY, int aWidth, int aHeight)
    77 void Pixmap::createFromImage(Image* aImage, int aX, int aY, int aWidth, int aHeight)
    78 {
    78     {
    79     GFX_LOG_FUNC_CALL();
    79     GFX_LOG_FUNC_CALL();
    80     Q_ASSERT(mPixmap.isNull());
    80     Q_ASSERT(mPixmap.isNull());
    81 
    81 
    82     // Get QPixmap from original
    82     // Check if the copy should be exactly same as the original
    83     QPixmap* src = aImage->getPixmap();
    83     if((aImage->getWidth() == aWidth) && (aImage->getHeight() == aHeight) || 
    84     if(!src)
    84         QRect(aX, aY, aWidth, aHeight).isEmpty())
    85     {
    85         {
       
    86         mPixmap = aImage->toPixmap();
       
    87         }
       
    88     // it's needed to make partial copy of the original
       
    89     else
       
    90         {
       
    91         switch(aImage->type())
       
    92             {
       
    93             case EImage:
       
    94                 {
       
    95                 mPixmap = QPixmap::fromImage(aImage->getConstImage()->copy(aX, aY, aWidth, aHeight));
       
    96                 break;
       
    97                 }
       
    98             case EPixmap:
       
    99                 {
       
   100                 mPixmap = aImage->getConstPixmap()->copy(aX, aY, aWidth, aHeight);
       
   101                 break;
       
   102                 }
       
   103             default:
       
   104                 throw GfxException(EGfxErrorIllegalArgument, "Unsupported source image type");
       
   105             }
       
   106         
       
   107         }
       
   108     if(mPixmap.isNull())
       
   109         {
    86         throw GfxException(EGfxErrorNoMemory, "Image (pixmap) creation failed");
   110         throw GfxException(EGfxErrorNoMemory, "Image (pixmap) creation failed");
    87     }
   111         }
    88 
   112     }
    89     // If specific values were given and they represent the whole pixmap exactly
       
    90     bool isWholePixmap = (src->size() == QSize(aWidth, aHeight)) && (aX == aY == 0);
       
    91 
       
    92     // Also an empty area means that the whole pixmap needs to be copied
       
    93     bool isEmptyArea = QRect(aX, aY, aWidth, aHeight).isEmpty();
       
    94 
       
    95     if( isWholePixmap || isEmptyArea )
       
    96     {
       
    97         // Assign to our copy using implicit sharing
       
    98         mPixmap = *src;
       
    99     }
       
   100     else
       
   101     {
       
   102         // Convert to QImage, copy the pixel data area, convert back to QPixmap
       
   103         mPixmap = src->copy(aX, aY, aWidth, aHeight);
       
   104     }
       
   105 
       
   106     if(mPixmap.isNull())
       
   107     {
       
   108         throw GfxException(EGfxErrorNoMemory, "Image (pixmap) creation failed");
       
   109     }
       
   110 }
       
   111 
   113 
   112 void Pixmap::createFromImageData(ImageDataWrapper* aData)
   114 void Pixmap::createFromImageData(ImageDataWrapper* aData)
   113 {
   115     {
   114     GFX_LOG_FUNC_CALL();
   116     GFX_LOG_FUNC_CALL();
   115     Q_ASSERT(mPixmap.isNull());
   117     Q_ASSERT(mPixmap.isNull());
   116 
   118 
   117     if(aData->getDepth() != 32)
   119     mPixmap = QPixmap::fromImage(imageDataToQImage(aData));
   118     {
   120 
   119         // Java side always converts the ImageData to 32 bit before passing it
   121     if(mPixmap.isNull())
   120         // to native side, bail out if we get something else
   122         {
   121         throw GfxException(EGfxErrorNoMemory, "Only 32 bit ImageData is supported in Image creation");
   123         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
   122     }
   124         }
   123 
   125     }
   124     int bpp = 4; // bit depth = 32, 4 bytes per pixel
       
   125     int size = aData->getWidth()*aData->getHeight()*bpp;
       
   126     char* pixelData = aData->getData(ImageDataWrapper::EPixelData);
       
   127 
       
   128     for(int index = 0; index < size; index += bpp)
       
   129     {
       
   130         int pixel = *(reinterpret_cast<int*>(pixelData+index));
       
   131 
       
   132         pixelData[index]   = (uchar)(pixel >> 24) & 0xFF;
       
   133         pixelData[index+1] = (uchar)(pixel >> 16) & 0xFF;
       
   134         pixelData[index+2] = (uchar)(pixel >> 8) & 0xFF;
       
   135         pixelData[index+3] = 0xFF; // Set alpha to opaque here, alpha channel data will be handled later
       
   136     }
       
   137 
       
   138     QImage image(reinterpret_cast<uchar*>(aData->getData(ImageDataWrapper::EPixelData)),
       
   139                                           aData->getWidth(),
       
   140                                           aData->getHeight(),
       
   141                                           aData->getBytesPerLine(),
       
   142                                           QImage::Format_ARGB32);
       
   143     if(image.isNull())
       
   144   {
       
   145     throw GfxException(EGfxErrorNoMemory, "QImage (Pixmap) creation failed");
       
   146     }
       
   147 
       
   148     // Set indexed palette (if one is set)
       
   149     if(!aData->isDirect())
       
   150     {
       
   151         image.setColorTable(*aData->getPaletteData()->getIndexedPalette());
       
   152     }
       
   153 
       
   154     mHasMask = false;
       
   155     mAlpha = aData->getAlpha();
       
   156 
       
   157     if(aData->getData(ImageDataWrapper::EMaskData))
       
   158     {
       
   159         QImage mask(reinterpret_cast<uchar*>(aData->getData(ImageDataWrapper::EMaskData)),
       
   160                                              aData->getWidth(),
       
   161                                              aData->getHeight(),
       
   162                                              QImage::Format_Mono);
       
   163         if(mask.isNull())
       
   164       {
       
   165         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) alpha channel creation failed");
       
   166         }
       
   167         image.setAlphaChannel(mask);
       
   168         mHasMask = true;
       
   169     }
       
   170     else if(mAlpha != -1)
       
   171     {
       
   172         // Global alpha is set, overrides alpha channel data
       
   173         QImage alpha(aData->getWidth(), aData->getHeight(), QImage::Format_Indexed8);
       
   174         if(alpha.isNull())
       
   175       {
       
   176         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) alpha channel creation failed");
       
   177         }
       
   178 
       
   179         alpha.fill(aData->getAlpha());
       
   180         image.setAlphaChannel(alpha);
       
   181     }
       
   182     else if(aData->getData(ImageDataWrapper::EAlphaData))
       
   183     {
       
   184         // Alpha channel data is set
       
   185         const int w = aData->getWidth();
       
   186         QImage alpha(reinterpret_cast<uchar*>(aData->getData(ImageDataWrapper::EAlphaData)),
       
   187                                               w,
       
   188                                               aData->getHeight(),
       
   189                                               w,
       
   190                                               QImage::Format_Indexed8);
       
   191         QVector<QRgb> colors(255);
       
   192         for(int i=0; i<255; i++)
       
   193             {
       
   194             colors[i] = qRgb(i, i, i);
       
   195             }
       
   196         alpha.setColorTable(colors);
       
   197         colors.clear();
       
   198 
       
   199         if(alpha.isNull())
       
   200       {
       
   201         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) alpha channel creation failed");
       
   202         }
       
   203         image.setAlphaChannel(alpha);
       
   204     }
       
   205 
       
   206     mPixmap = QPixmap::fromImage(image);
       
   207 
       
   208     if(mPixmap.isNull())
       
   209     {
       
   210         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
       
   211     }
       
   212 }
       
   213 
   126 
   214 void Pixmap::createFromRGB(int* aRgbdata, int aWidth, int aHeight, bool aHasAlpha)
   127 void Pixmap::createFromRGB(int* aRgbdata, int aWidth, int aHeight, bool aHasAlpha)
   215 {
   128     {
   216     GFX_LOG_FUNC_CALL();
   129     GFX_LOG_FUNC_CALL();
   217     Q_ASSERT(mPixmap.isNull());
   130     Q_ASSERT(mPixmap.isNull());
   218 
   131 
   219     // Create QImage from rgbdata as QPixmap does not directly support that
   132     // Create QImage from rgbdata as QPixmap does not directly support that
   220     QImage tmpImage(reinterpret_cast<unsigned char*>(aRgbdata), aWidth, aHeight,
   133     QImage tmpImage(reinterpret_cast<unsigned char*>(aRgbdata), aWidth, aHeight,
   221         (aHasAlpha ? QImage::Format_ARGB32 : QImage::Format_RGB32));
   134         (aHasAlpha ? QImage::Format_ARGB32 : QImage::Format_RGB32));
   222 
   135 
   223     // Validate creation
   136     // Validate creation
   224     if(tmpImage.isNull())
   137     if(tmpImage.isNull())
   225     {
   138         {
   226         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
   139         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
   227     }
   140         }
   228 
   141 
   229     // Store as QPixmap
   142     // Store as QPixmap
   230     mPixmap = QPixmap::fromImage(tmpImage);
   143     mPixmap = QPixmap::fromImage(tmpImage);
   231 
   144 
   232     // Validate conversion
   145     // Validate conversion
   233     if(mPixmap.isNull())
   146     if(mPixmap.isNull())
   234     {
   147         {
   235         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
   148         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
   236     }
   149         }
   237 }
   150     }
   238 
   151 
   239 void Pixmap::dispose()
   152 void Pixmap::dispose()
   240 {
   153     {
   241     GFX_LOG_FUNC_CALL();
   154     GFX_LOG_FUNC_CALL();
   242     delete this;
   155     delete this;
   243 }
   156     }
   244 
   157 
   245 QPaintDevice* Pixmap::getBindable()
   158 QPaintDevice* Pixmap::getBindable()
   246 {
   159     {
   247     GFX_LOG_FUNC_CALL();
   160     GFX_LOG_FUNC_CALL();
   248     return static_cast<QPaintDevice*>(&mPixmap);
   161     return static_cast<QPaintDevice*>(&mPixmap);
   249 }
   162     }
   250 
   163 
   251 int Pixmap::getFormat()
   164 TImageFormat Pixmap::getFormat()
   252 {
   165     {
   253     GFX_LOG_FUNC_CALL();
   166     GFX_LOG_FUNC_CALL();
   254     QImage img = mPixmap.toImage();
   167     QImage img = mPixmap.toImage();
   255     // Validate conversion
   168     // Validate conversion
   256     if(img.isNull()) {
   169     if(img.isNull()) 
       
   170         {
   257         throw GfxException(EGfxErrorNoMemory, "Convertion from QPixmap to QImage failed");
   171         throw GfxException(EGfxErrorNoMemory, "Convertion from QPixmap to QImage failed");
   258     }
   172         }
   259     int imgFormat = img.format();
   173     return mapQtFormatToInternal(img.format());
   260 
   174     }
   261     switch (imgFormat) {
       
   262         case QImage::Format_ARGB32:
       
   263             return EFormatARGB32;
       
   264         case QImage::Format_RGB32:
       
   265             return EFormatRGB32;
       
   266         case QImage::Format_ARGB32_Premultiplied:
       
   267             return EFormatARGB32Premultiplied;
       
   268          case QImage::Format_RGB16:
       
   269             return EFormatRGB16;
       
   270          case QImage::Format_RGB555:
       
   271             return EFormatRGB555;
       
   272          case QImage::Format_RGB444:
       
   273             return EFormatRGB444;
       
   274          case QImage::Format_ARGB4444_Premultiplied:
       
   275             return EFormatARGB4444Premultiplied;
       
   276          case QImage::Format_Mono:
       
   277             return EFormatMONO;
       
   278          default:
       
   279             return EFormatNone;
       
   280     }
       
   281 }
       
   282 
   175 
   283 int Pixmap::getHeight()
   176 int Pixmap::getHeight()
   284 {
   177     {
   285     GFX_LOG_FUNC_CALL();
   178     GFX_LOG_FUNC_CALL();
   286     return mPixmap.height();
   179     return mPixmap.height();
   287 }
   180     }
       
   181 
       
   182 const QImage* Pixmap::getConstImage()
       
   183     {
       
   184     GFX_LOG_FUNC_CALL();
       
   185     return NULL;
       
   186     }
       
   187 
       
   188 QImage* Pixmap::getImage()
       
   189     {
       
   190     GFX_LOG_FUNC_CALL();
       
   191     return NULL;
       
   192     }
       
   193 
       
   194 const QPixmap* Pixmap::getConstPixmap()
       
   195     {
       
   196     GFX_LOG_FUNC_CALL();
       
   197     return &mPixmap;
       
   198     }
   288 
   199 
   289 QPixmap* Pixmap::getPixmap()
   200 QPixmap* Pixmap::getPixmap()
   290 {
   201     {
   291     GFX_LOG_FUNC_CALL();
   202     GFX_LOG_FUNC_CALL();
   292     return &mPixmap;
   203     return &mPixmap;
   293 }
   204     }
   294 
   205 
   295 int Pixmap::getWidth()
   206 int Pixmap::getWidth()
   296 {
   207     {
   297     GFX_LOG_FUNC_CALL();
   208     GFX_LOG_FUNC_CALL();
   298     return mPixmap.width();
   209     return mPixmap.width();
   299 }
   210     }
   300 
       
   301 int Pixmap::getAlpha()
       
   302 {
       
   303     GFX_LOG_FUNC_CALL();
       
   304     return mAlpha;
       
   305 }
       
   306 
       
   307 bool Pixmap::hasMask()
       
   308 {
       
   309     GFX_LOG_FUNC_CALL();
       
   310     return mHasMask;
       
   311 }
       
   312 
   211 
   313 void Pixmap::getRgb(int* aRgbdata, int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight)
   212 void Pixmap::getRgb(int* aRgbdata, int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight)
   314 {
   213     {
   315     GFX_LOG_FUNC_CALL();
   214     GFX_LOG_FUNC_CALL();
   316 
   215 
   317     // Convert to QImage in order to access pixels
   216     // Convert to QImage in order to access pixels
   318     QImage image = mPixmap.toImage();
   217     QImage image = mPixmap.toImage();
   319 
   218 
   320     // Validate conversion
   219     // Validate conversion
   321     if(image.isNull())
   220     if(image.isNull())
   322         {
   221         {
   323         throw GfxException(EGfxErrorNoMemory, "Convertion from QPixmap to QImage failed");
   222         throw GfxException(EGfxErrorNoMemory, "Convertion from QPixmap to QImage failed");
   324         }
   223         }
   325 
   224     doGetRgb(image, aRgbdata, aOffset, aScanlength, aX, aY, aWidth, aHeight);
   326     if(aX != 0 || aY != 0 || aWidth < image.width() || aHeight < image.height())
   225     }
   327         {
   226 
   328         image = image.copy(aX, aY, aWidth, aHeight);
   227 
   329         if(image.isNull())
   228 void Pixmap::getRgb(char* aRgbdata, char* aTransparencyMask,int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight, int aFormat) {
   330             {
       
   331             throw GfxException(EGfxErrorNoMemory, "copying from original image failed");
       
   332             }
       
   333         }
       
   334 
       
   335 
       
   336     // If image is not 32bpp we need to convert it
       
   337     if(image.format() != QImage::Format_RGB32 &&
       
   338        image.format() != QImage::Format_ARGB32)
       
   339         {
       
   340         image = image.convertToFormat(QImage::Format_ARGB32);
       
   341         if(image.isNull())
       
   342             {
       
   343             throw GfxException(EGfxErrorNoMemory, "format convertion to 32bpp failed");
       
   344             }
       
   345         }
       
   346 
       
   347     // Temporary storage for pixels
       
   348     QRgb* pixel = NULL;
       
   349 
       
   350     // dataArray index, start from offset
       
   351     int targetIndex = aOffset;
       
   352 
       
   353     // Iterate through lines
       
   354     for(int b = 0; b < aHeight; ++b)
       
   355     {
       
   356         // Obtain pointer to start of current line (y)
       
   357         const unsigned char* lineStart = image.scanLine(b);
       
   358 
       
   359         // Iterate through pixels on each line
       
   360         for (int a = 0; a < aWidth; ++a)
       
   361         {
       
   362             // Set the current pixel, relative to line start
       
   363             pixel = ((QRgb*)lineStart) + a;
       
   364 
       
   365             // Move target pointer to the next slot
       
   366             targetIndex = aOffset + a + (b * aScanlength);
       
   367             // Shift pixels to correct places, needed for 32-bit format
       
   368             // as the bits order in memory may vary between systems
       
   369             aRgbdata[targetIndex] =  ((qAlpha(*pixel) & 0xff) << 24) |
       
   370                                      ((qRed(*pixel)   & 0xff) << 16) |
       
   371                                      ((qGreen(*pixel) & 0xff) << 8 ) |
       
   372                                      ((qBlue(*pixel)  & 0xff));
       
   373         }
       
   374     }
       
   375 
       
   376 }
       
   377 
       
   378 
       
   379 void Pixmap::getRgb(char* aRgbdata, char* aTransparencyMask,int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight, int /*aFormat*/) {
       
   380 
   229 
   381     GFX_LOG_FUNC_CALL();
   230     GFX_LOG_FUNC_CALL();
   382 
   231 
   383     // Convert to QImage in order to access pixels
   232     // Convert to QImage in order to access pixels
   384     QImage image = mPixmap.toImage();
   233     QImage image = mPixmap.toImage();
   385 
   234 
   386     // Validate conversion
   235     // Validate conversion
   387     if(image.isNull()) {
   236     if(image.isNull()) 
       
   237         {
   388         throw GfxException(EGfxErrorNoMemory, "Conversion from QPixmap to QImage failed");
   238         throw GfxException(EGfxErrorNoMemory, "Conversion from QPixmap to QImage failed");
   389     }
   239         }
   390 
   240     doGetRgb(image, aRgbdata, aTransparencyMask, aOffset, aScanlength, aX, aY, aWidth, aHeight, aFormat);
   391      if(aX != 0 || aY != 0 || aWidth < image.width() || aHeight < image.height())
   241     }
   392         {
   242 
   393         image = image.copy(aX, aY, aWidth, aHeight);
   243 void Pixmap::getRgb(short* aRgbdata, int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight, int aFormat) 
   394         if(image.isNull())
   244     {
   395             {
   245     GFX_LOG_FUNC_CALL();
   396             throw GfxException(EGfxErrorNoMemory, "copying from original image failed");
   246 
   397             }
       
   398         }
       
   399 
       
   400     if(aScanlength < 0)
       
   401         {
       
   402          image = image.mirrored(false, true);
       
   403          if(image.isNull())
       
   404              {
       
   405              throw GfxException(EGfxErrorNoMemory, "Mirroring failed");
       
   406              }
       
   407         }
       
   408 
       
   409     // If image is not monochrome we need to convert it
       
   410     if(image.format() != QImage::Format_Mono)
       
   411     {
       
   412         image = image.convertToFormat(QImage::Format_Mono);
       
   413         if(image.isNull())
       
   414         {
       
   415             throw GfxException(EGfxErrorNoMemory, "Format conversion to 8bpp failed");
       
   416         }
       
   417     }
       
   418 
       
   419     // dataArray index, start from offset
       
   420     int targetIndex = aOffset;
       
   421 
       
   422     const unsigned char* imageStart = image.bits();
       
   423     QImage mask = image.alphaChannel();
       
   424     const unsigned char* maskStart = mask.bits();
       
   425 
       
   426     // Find the number of full bytes
       
   427     int fullBytes = aWidth/8;
       
   428     int bpl = image.bytesPerLine();
       
   429 
       
   430     if(bpl == fullBytes)
       
   431     {
       
   432         memcpy(aRgbdata+targetIndex, imageStart, bpl*aHeight);
       
   433         memcpy(aTransparencyMask+targetIndex, maskStart, bpl*aHeight);
       
   434     }
       
   435     else
       
   436     {
       
   437         memcpy(aRgbdata+targetIndex, imageStart, fullBytes*aHeight + aHeight);
       
   438         memcpy(aTransparencyMask+targetIndex, maskStart, fullBytes*aHeight + aHeight);
       
   439     }
       
   440 
       
   441 }
       
   442 
       
   443 void Pixmap::getRgb(short* aRgbdata, int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight, int aFormat) {
       
   444     GFX_LOG_FUNC_CALL();
       
   445 
       
   446     // Match format to QT
       
   447     int format;
       
   448     switch (aFormat) {
       
   449         case EFormatRGB555:
       
   450             format = QImage::Format_RGB555;
       
   451             break;
       
   452         case EFormatRGB16:
       
   453             format = QImage::Format_RGB16;
       
   454             break;
       
   455          case EFormatRGB444:
       
   456             format = QImage::Format_RGB444;
       
   457             break;
       
   458          case EFormatARGB4444Premultiplied:
       
   459             format = QImage::Format_ARGB4444_Premultiplied;
       
   460             break;
       
   461          default:
       
   462             format = QImage::Format_RGB16;
       
   463     }
       
   464     // Convert to QImage in order to access pixels
   247     // Convert to QImage in order to access pixels
   465     QImage image = mPixmap.toImage();
   248     QImage image = mPixmap.toImage();
   466 
   249 
   467     // Validate conversion
   250     // Validate conversion
   468     if(image.isNull())
   251     if(image.isNull())
   469     {
   252         {
   470         throw GfxException(EGfxErrorNoMemory, "Conversion from QPixmap to QImage failed");
   253         throw GfxException(EGfxErrorNoMemory, "Conversion from QPixmap to QImage failed");
   471     }
   254         }
   472 
   255     doGetRgb(image, aRgbdata, aOffset, aScanlength, aX, aY, aWidth, aHeight, aFormat);
   473     if(aX != 0 || aY != 0 || aWidth < image.width() || aHeight < image.height())
   256     }
   474         {
   257 
   475         image = image.copy(aX, aY, aWidth, aHeight);
   258 const QImage Pixmap::toConstImage()
   476         if(image.isNull())
   259     {
   477             {
   260     GFX_LOG_FUNC_CALL();
   478             throw GfxException(EGfxErrorNoMemory, "copying from original image failed");
   261     return mPixmap.toImage();
   479             }
   262     }
   480         }
       
   481 
       
   482 
       
   483     // If image is not format we need, convert it
       
   484     if(image.format() != format)
       
   485     {
       
   486         image = image.convertToFormat((QImage::Format)format);
       
   487         if(image.isNull())
       
   488         {
       
   489             throw GfxException(EGfxErrorNoMemory, "format convertion to 16bpp failed");
       
   490         }
       
   491     }
       
   492 
       
   493     // Temporary storage for pixels
       
   494     short* pixel = NULL;
       
   495     // dataArray index, start from offset
       
   496     int targetIndex = aOffset;
       
   497 
       
   498     // Iterate through lines
       
   499     for(int b=0; b < aHeight; b++)
       
   500     {
       
   501         // Obtain pointer to start of current line (y)
       
   502         const unsigned char* lineStart = image.scanLine(b);
       
   503         // Iterate through pixels on each line
       
   504         for(int a=0; a < aWidth; a++)
       
   505         {
       
   506             // Set the current pixel, relative to line start
       
   507             pixel = ((short*)lineStart) + a;
       
   508             // Move target pointer to the next slot
       
   509             targetIndex = aOffset + a + (b * aScanlength);
       
   510             aRgbdata[targetIndex] =  *pixel;
       
   511         }
       
   512     }
       
   513 }
       
   514 
   263 
   515 QImage Pixmap::toImage()
   264 QImage Pixmap::toImage()
   516 {
   265     {
       
   266     GFX_LOG_FUNC_CALL();
   517     return mPixmap.toImage();
   267     return mPixmap.toImage();
   518 }
   268     }
       
   269 
       
   270 QPixmap Pixmap::toPixmap()
       
   271     {
       
   272     GFX_LOG_FUNC_CALL();
       
   273     return QPixmap(mPixmap);
       
   274     }
   519 
   275 
   520 void Pixmap::transform(TTransform aTransform)
   276 void Pixmap::transform(TTransform aTransform)
   521 {
   277     {
   522     GFX_LOG_FUNC_CALL();
   278     GFX_LOG_FUNC_CALL();
   523 
   279     mPixmap = mPixmap.transformed(generateTransformMatrix(aTransform), Qt::FastTransformation);
   524     // For rotation along z-axis
   280     if(mPixmap.isNull())
   525     QTransform imageTransform;
   281         {
   526     bool flip = false;
   282         throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed");
   527     bool rotate = true;
   283         }
   528 
   284     }
   529     switch(aTransform) {
       
   530         case ETransNone:
       
   531             // No transform or mirror
       
   532             return;
       
   533         case ETransRot90:
       
   534             imageTransform.rotate(90, Qt::ZAxis);
       
   535             break;
       
   536         case ETransRot180:
       
   537             imageTransform.rotate(180, Qt::ZAxis);
       
   538             break;
       
   539         case ETransRot270:
       
   540             imageTransform.rotate(270, Qt::ZAxis);
       
   541             break;
       
   542         case ETransMirror:
       
   543             flip = true;
       
   544             rotate = false;
       
   545             break;
       
   546         case ETransMirrorRot90:
       
   547             imageTransform.rotate(90, Qt::ZAxis);
       
   548             flip = true;
       
   549             break;
       
   550         case ETransMirrorRot180:
       
   551             imageTransform.rotate(180, Qt::ZAxis);
       
   552             flip = true;
       
   553             break;
       
   554         case ETransMirrorRot270:
       
   555             imageTransform.rotate(270, Qt::ZAxis);
       
   556             flip = true;
       
   557             break;
       
   558         default:
       
   559             Q_ASSERT_X(false, "Graphics", "Transform type not recognized");
       
   560             return;
       
   561     }
       
   562 
       
   563     // Mirror image first if requested
       
   564     if(flip)
       
   565     {
       
   566         QTransform flipTransform;
       
   567         flipTransform.rotate(180,Qt::YAxis);
       
   568 
       
   569         // Create temp pixmap for flipped
       
   570         QPixmap temp = mPixmap.transformed(flipTransform, Qt::FastTransformation);
       
   571 
       
   572         // Validate transformation
       
   573         if(temp.isNull())
       
   574         {
       
   575             throw GfxException(EGfxErrorNoMemory, "temp buffer alloc failed");
       
   576         }
       
   577 
       
   578         // Free original pixmap and store new
       
   579         mPixmap = temp;
       
   580     }
       
   581 
       
   582     // Then rotate
       
   583     if(rotate)
       
   584     {
       
   585         // Create temp pixmap for rotate
       
   586         QPixmap temp = mPixmap.transformed(imageTransform, Qt::FastTransformation);
       
   587 
       
   588         // Validate alloc
       
   589         if(temp.isNull())
       
   590         {
       
   591             throw GfxException(EGfxErrorNoMemory, "temp buffer alloc failed");
       
   592         }
       
   593 
       
   594         // Free original image and store new
       
   595         mPixmap = temp;
       
   596     }
       
   597 }
       
   598 
   285 
   599 TImageType Pixmap::type()
   286 TImageType Pixmap::type()
   600 {
   287     {
   601     GFX_LOG_FUNC_CALL();
   288     GFX_LOG_FUNC_CALL();
   602     return EPixmap;
   289     return EPixmap;
   603 }
   290     }
   604 
   291 
   605 bool Pixmap::hasAlphaChannel()
   292 bool Pixmap::hasAlphaChannel()
   606 {
   293     {
   607     GFX_LOG_FUNC_CALL();
   294     GFX_LOG_FUNC_CALL();
   608     return mPixmap.hasAlphaChannel();
   295     return mPixmap.hasAlphaChannel();
   609 }
   296     }
   610 
   297 
   611 } // namespace GFX
   298 } // namespace GFX
   612 } // namespace Java
   299 } // namespace Java