Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void ImageDataUtil::CopyPixels (Image* image, Image* sourceImage, Rectangle* sourceRect, Vector2* destPoint, Image* alphaImage, Vector2* alphaPoint, bool mergeAlpha) {
- uint8_t* sourceData = (uint8_t*)sourceImage->buffer->data->Data ();
- uint8_t* destData = (uint8_t*)image->buffer->data->Data ();
- ImageDataView sourceView = ImageDataView (sourceImage, sourceRect);
- Rectangle destRect = Rectangle (destPoint->x, destPoint->y, sourceView.width, sourceView.height);
- ImageDataView destView = ImageDataView (image, &destRect);
- PixelFormat sourceFormat = sourceImage->buffer->format;
- PixelFormat destFormat = image->buffer->format;
- bool sourcePremultiplied = sourceImage->buffer->premultiplied;
- bool destPremultiplied = image->buffer->premultiplied;
- int sourcePosition, destPosition;
- RGBA sourcePixel;
- if (!mergeAlpha || !sourceImage->buffer->transparent) {
- if(sourceFormat == destFormat && sourcePremultiplied == destPremultiplied) {
- //I need the syntax for an ImageBuffer.blit() call or something like that to draw the whole rectangle
- //in one whack (as a series of single-row memcpy()'s rather than read/write each pixel by hand
- //trying this for now:
- for (int y = 0; y < destView.height; y++) {
- sourcePosition = sourceView.Row (y);
- destPosition = destView.Row (y);
- image->buffer->BlitRow(sourceData, sourcePosition, destPosition, sourceView.width, destView.x, destView.y+y);
- }
- }
- else {
- for (int y = 0; y < destView.height; y++) {
- sourcePosition = sourceView.Row (y);
- destPosition = destView.Row (y);
- for (int x = 0; x < destView.width; x++) {
- sourcePixel.ReadUInt8 (sourceData, sourcePosition, sourceFormat, sourcePremultiplied);
- sourcePixel.WriteUInt8 (destData, destPosition, destFormat, destPremultiplied);
- sourcePosition += 4;
- destPosition += 4;
- }
- }
- }
- } else {
- float sourceAlpha, destAlpha, oneMinusSourceAlpha, blendAlpha;
- RGBA destPixel;
- if (alphaImage == 0) {
- for (int y = 0; y < destView.height; y++) {
- sourcePosition = sourceView.Row (y);
- destPosition = destView.Row (y);
- for (int x = 0; x < destView.width; x++) {
- sourcePixel.ReadUInt8 (sourceData, sourcePosition, sourceFormat, sourcePremultiplied);
- destPixel.ReadUInt8 (destData, destPosition, destFormat, destPremultiplied);
- sourceAlpha = sourcePixel.a / 255.0;
- destAlpha = destPixel.a / 255.0;
- oneMinusSourceAlpha = 1 - sourceAlpha;
- blendAlpha = sourceAlpha + (destAlpha * oneMinusSourceAlpha);
- if (blendAlpha == 0) {
- destPixel.Set (0, 0, 0, 0);
- } else {
- destPixel.r = __clamp[int (0.5 + (sourcePixel.r * sourceAlpha + destPixel.r * destAlpha * oneMinusSourceAlpha) / blendAlpha)];
- destPixel.g = __clamp[int (0.5 + (sourcePixel.g * sourceAlpha + destPixel.g * destAlpha * oneMinusSourceAlpha) / blendAlpha)];
- destPixel.b = __clamp[int (0.5 + (sourcePixel.b * sourceAlpha + destPixel.b * destAlpha * oneMinusSourceAlpha) / blendAlpha)];
- destPixel.a = __clamp[int (0.5 + blendAlpha * 255.0)];
- }
- destPixel.WriteUInt8 (destData, destPosition, destFormat, destPremultiplied);
- sourcePosition += 4;
- destPosition += 4;
- }
- }
- } else {
- uint8_t* alphaData = (uint8_t*)alphaImage->buffer->data->Data ();
- PixelFormat alphaFormat = alphaImage->buffer->format;
- bool alphaPremultiplied = alphaImage->buffer->premultiplied;
- Rectangle alphaRect = Rectangle (alphaPoint->x, alphaPoint->y, destView.width, destView.height);
- ImageDataView alphaView = ImageDataView (alphaImage, &alphaRect);
- int alphaPosition;
- RGBA alphaPixel;
- for (int y = 0; y < alphaView.height; y++) {
- sourcePosition = sourceView.Row (y);
- destPosition = destView.Row (y);
- alphaPosition = alphaView.Row (y);
- for (int x = 0; x < alphaView.width; x++) {
- sourcePixel.ReadUInt8 (sourceData, sourcePosition, sourceFormat, sourcePremultiplied);
- destPixel.ReadUInt8 (destData, destPosition, destFormat, destPremultiplied);
- alphaPixel.ReadUInt8 (alphaData, alphaPosition, alphaFormat, alphaPremultiplied);
- sourceAlpha = alphaPixel.a / 0xFF;
- destAlpha = destPixel.a / 0xFF;
- oneMinusSourceAlpha = 1 - sourceAlpha;
- blendAlpha = sourceAlpha + (destAlpha * oneMinusSourceAlpha);
- if (blendAlpha == 0) {
- destPixel.Set (0, 0, 0, 0);
- } else {
- destPixel.r = __clamp[int (0.5 + (sourcePixel.r * sourceAlpha + destPixel.r * destAlpha * oneMinusSourceAlpha) / blendAlpha)];
- destPixel.g = __clamp[int (0.5 + (sourcePixel.g * sourceAlpha + destPixel.g * destAlpha * oneMinusSourceAlpha) / blendAlpha)];
- destPixel.b = __clamp[int (0.5 + (sourcePixel.b * sourceAlpha + destPixel.b * destAlpha * oneMinusSourceAlpha) / blendAlpha)];
- destPixel.a = __clamp[int (0.5 + blendAlpha * 255.0)];
- }
- destPixel.WriteUInt8 (destData, destPosition, destFormat, destPremultiplied);
- sourcePosition += 4;
- destPosition += 4;
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement