зеркало из https://github.com/mozilla/gecko-dev.git
Bug 460969 - Fix image from clipboard code; r=netzen
This commit is contained in:
Родитель
7fa33d3d7e
Коммит
3600f06313
|
@ -194,33 +194,31 @@ nsImageFromClipboard ::GetEncodedImageStream (unsigned char * aClipboardData, co
|
||||||
// neg. heights mean the Y axis is inverted and we don't handle that case
|
// neg. heights mean the Y axis is inverted and we don't handle that case
|
||||||
NS_ENSURE_TRUE(height > 0, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(height > 0, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
unsigned char * rgbData = new unsigned char[width * height * 3 /* RGB */];
|
static mozilla::fallible_t fallible = mozilla::fallible_t();
|
||||||
|
unsigned char * rgbaData = new (fallible) unsigned char[width * height * 4 /* RGBA */];
|
||||||
|
if (!rgbaData)
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
if (rgbData) {
|
BYTE * pGlobal = (BYTE *) aClipboardData;
|
||||||
BYTE * pGlobal = (BYTE *) aClipboardData;
|
// Convert the clipboard image into RGB packed pixel data
|
||||||
// Convert the clipboard image into RGB packed pixel data
|
rv = ConvertColorBitMap((unsigned char *) (pGlobal + header->bmiHeader.biSize), header, rgbaData);
|
||||||
rv = ConvertColorBitMap((unsigned char *) (pGlobal + header->bmiHeader.biSize), header, rgbData);
|
// if that succeeded, encode the bitmap as aMIMEFormat data. Don't return early or we risk leaking rgbData
|
||||||
// if that succeeded, encode the bitmap as aMIMEFormat data. Don't return early or we risk leaking rgbData
|
if (NS_SUCCEEDED(rv)) {
|
||||||
if (NS_SUCCEEDED(rv)) {
|
nsCAutoString encoderCID(NS_LITERAL_CSTRING("@mozilla.org/image/encoder;2?type="));
|
||||||
nsCAutoString encoderCID(NS_LITERAL_CSTRING("@mozilla.org/image/encoder;2?type="));
|
// Map image/jpg to image/jpeg (which is how the encoder is registered).
|
||||||
|
if (strcmp(aMIMEFormat, kJPEGImageMime) == 0)
|
||||||
// Map image/jpg to image/jpeg (which is how the encoder is registered).
|
encoderCID.Append("image/jpeg");
|
||||||
if (strcmp(aMIMEFormat, kJPGImageMime) == 0)
|
else
|
||||||
encoderCID.Append("image/jpeg");
|
encoderCID.Append(aMIMEFormat);
|
||||||
else
|
nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(encoderCID.get(), &rv);
|
||||||
encoderCID.Append(aMIMEFormat);
|
if (NS_SUCCEEDED(rv)){
|
||||||
nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(encoderCID.get(), &rv);
|
rv = encoder->InitFromData(rgbaData, 0, width, height, 4 * width /* RGBA * # pixels in a row */,
|
||||||
if (NS_SUCCEEDED(rv)){
|
imgIEncoder::INPUT_FORMAT_RGBA, EmptyString());
|
||||||
rv = encoder->InitFromData(rgbData, 0, width, height, 3 * width /* RGB * # pixels in a row */,
|
if (NS_SUCCEEDED(rv))
|
||||||
imgIEncoder::INPUT_FORMAT_RGB, EmptyString());
|
encoder->QueryInterface(NS_GET_IID(nsIInputStream), (void **) aInputStream);
|
||||||
if (NS_SUCCEEDED(rv))
|
|
||||||
encoder->QueryInterface(NS_GET_IID(nsIInputStream), (void **) aInputStream);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
delete [] rgbData;
|
}
|
||||||
}
|
delete[] rgbaData;
|
||||||
else
|
|
||||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
} // GetImage
|
} // GetImage
|
||||||
|
@ -257,7 +255,7 @@ nsImageFromClipboard::InvertRows(unsigned char * aInitialBuffer, PRUint32 aSizeO
|
||||||
//
|
//
|
||||||
// ConvertColorBitMap
|
// ConvertColorBitMap
|
||||||
//
|
//
|
||||||
// Takes the clipboard bitmap and converts it into a RGB packed pixel values.
|
// Takes the clipboard bitmap and converts it into a RGBA packed pixel values.
|
||||||
//
|
//
|
||||||
nsresult
|
nsresult
|
||||||
nsImageFromClipboard::ConvertColorBitMap(unsigned char * aInputBuffer, PBITMAPINFO pBitMapInfo, unsigned char * aOutBuffer)
|
nsImageFromClipboard::ConvertColorBitMap(unsigned char * aInputBuffer, PBITMAPINFO pBitMapInfo, unsigned char * aOutBuffer)
|
||||||
|
@ -324,6 +322,7 @@ nsImageFromClipboard::ConvertColorBitMap(unsigned char * aInputBuffer, PBITMAPIN
|
||||||
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbRed;
|
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbRed;
|
||||||
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbGreen;
|
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbGreen;
|
||||||
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbBlue;
|
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbBlue;
|
||||||
|
aOutBuffer[writeIndex++] = 0xFF;
|
||||||
numPixelsLeftInRow--;
|
numPixelsLeftInRow--;
|
||||||
}
|
}
|
||||||
pos += 1;
|
pos += 1;
|
||||||
|
@ -336,6 +335,7 @@ nsImageFromClipboard::ConvertColorBitMap(unsigned char * aInputBuffer, PBITMAPIN
|
||||||
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbRed;
|
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbRed;
|
||||||
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbGreen;
|
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbGreen;
|
||||||
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbBlue;
|
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbBlue;
|
||||||
|
aOutBuffer[writeIndex++] = 0xFF;
|
||||||
numPixelsLeftInRow--;
|
numPixelsLeftInRow--;
|
||||||
|
|
||||||
if (numPixelsLeftInRow) // now read the second pixel
|
if (numPixelsLeftInRow) // now read the second pixel
|
||||||
|
@ -344,6 +344,7 @@ nsImageFromClipboard::ConvertColorBitMap(unsigned char * aInputBuffer, PBITMAPIN
|
||||||
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbRed;
|
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbRed;
|
||||||
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbGreen;
|
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbGreen;
|
||||||
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbBlue;
|
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbBlue;
|
||||||
|
aOutBuffer[writeIndex++] = 0xFF;
|
||||||
numPixelsLeftInRow--;
|
numPixelsLeftInRow--;
|
||||||
}
|
}
|
||||||
pos += 1;
|
pos += 1;
|
||||||
|
@ -353,6 +354,7 @@ nsImageFromClipboard::ConvertColorBitMap(unsigned char * aInputBuffer, PBITMAPIN
|
||||||
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[aInputBuffer[index]].rgbRed;
|
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[aInputBuffer[index]].rgbRed;
|
||||||
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[aInputBuffer[index]].rgbGreen;
|
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[aInputBuffer[index]].rgbGreen;
|
||||||
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[aInputBuffer[index]].rgbBlue;
|
aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[aInputBuffer[index]].rgbBlue;
|
||||||
|
aOutBuffer[writeIndex++] = 0xFF;
|
||||||
numPixelsLeftInRow--;
|
numPixelsLeftInRow--;
|
||||||
pos += 1;
|
pos += 1;
|
||||||
break;
|
break;
|
||||||
|
@ -371,6 +373,7 @@ nsImageFromClipboard::ConvertColorBitMap(unsigned char * aInputBuffer, PBITMAPIN
|
||||||
aOutBuffer[writeIndex++] = redValue;
|
aOutBuffer[writeIndex++] = redValue;
|
||||||
aOutBuffer[writeIndex++] = greenValue;
|
aOutBuffer[writeIndex++] = greenValue;
|
||||||
aOutBuffer[writeIndex++] = blueValue;
|
aOutBuffer[writeIndex++] = blueValue;
|
||||||
|
aOutBuffer[writeIndex++] = 0xFF;
|
||||||
numPixelsLeftInRow--;
|
numPixelsLeftInRow--;
|
||||||
pos += 2;
|
pos += 2;
|
||||||
}
|
}
|
||||||
|
@ -383,14 +386,22 @@ nsImageFromClipboard::ConvertColorBitMap(unsigned char * aInputBuffer, PBITMAPIN
|
||||||
aOutBuffer[writeIndex++] = (val & colorMasks.red) >> colorMasks.redRightShift << colorMasks.redLeftShift;
|
aOutBuffer[writeIndex++] = (val & colorMasks.red) >> colorMasks.redRightShift << colorMasks.redLeftShift;
|
||||||
aOutBuffer[writeIndex++] = (val & colorMasks.green) >> colorMasks.greenRightShift << colorMasks.greenLeftShift;
|
aOutBuffer[writeIndex++] = (val & colorMasks.green) >> colorMasks.greenRightShift << colorMasks.greenLeftShift;
|
||||||
aOutBuffer[writeIndex++] = (val & colorMasks.blue) >> colorMasks.blueRightShift << colorMasks.blueLeftShift;
|
aOutBuffer[writeIndex++] = (val & colorMasks.blue) >> colorMasks.blueRightShift << colorMasks.blueLeftShift;
|
||||||
|
aOutBuffer[writeIndex++] = 0xFF;
|
||||||
numPixelsLeftInRow--;
|
numPixelsLeftInRow--;
|
||||||
|
// If biCompression == BI_BITFIELDS, bpp != 24, since BI_BITFIELDS
|
||||||
|
// only supports 16 and 32 bpp. Hence, bpp == 32, and we can always
|
||||||
|
// read 4 bytes here.
|
||||||
pos += 4; // we read in 4 bytes of data in order to process this pixel
|
pos += 4; // we read in 4 bytes of data in order to process this pixel
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aOutBuffer[writeIndex++] = aInputBuffer[index+2];
|
aOutBuffer[writeIndex++] = aInputBuffer[index+2];
|
||||||
aOutBuffer[writeIndex++] = aInputBuffer[index+1];
|
aOutBuffer[writeIndex++] = aInputBuffer[index+1];
|
||||||
aOutBuffer[writeIndex++] = aInputBuffer[index];
|
aOutBuffer[writeIndex++] = aInputBuffer[index];
|
||||||
|
if (bytesPerPixel > 3)
|
||||||
|
aOutBuffer[writeIndex++] = aInputBuffer[index+3];
|
||||||
|
else
|
||||||
|
aOutBuffer[writeIndex++] = 0xFF;
|
||||||
numPixelsLeftInRow--;
|
numPixelsLeftInRow--;
|
||||||
pos += bytesPerPixel; // 3 bytes for 24 bit data, 4 bytes for 32 bit data (we skip over the 4th byte)...
|
pos += bytesPerPixel; // 3 bytes for 24 bit data, 4 bytes for 32 bit data (we skip over the 4th byte)...
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче