URL GetAttachmentIconURL(URL &base_url, const OpStringC& filename, BOOL big_attachment_icon) { big_attachment_icon = true; uni_char *tempurl = (uni_char *) g_memory_manager->GetTempBuf2k(); uni_snprintf(tempurl, UNICODE_DOWNSIZE(g_memory_manager->GetTempBuf2kLen())-1, UNI_L("attachment:/icon/%lu.bmp"), ++ icon_counter); URL icon = urlManager->GetURL(base_url, tempurl, (uni_char *) NULL); if (icon.IsEmpty()) return icon; OpBitmap *bmp = GetAttachmentIconOpBitmap(filename, big_attachment_icon); if(!bmp) { return URL(); } int w,h; w = bmp->Width(); h = bmp->Height(); int imageSize = w * h * 3; UINT32 biHeaderSize = 9*sizeof(UINT32) + 2*sizeof(UINT16); UINT32 bfHeaderSize = 3*sizeof(UINT16) + 2*sizeof(UINT32); #ifdef OPERA_BIG_ENDIAN UINT16 bfType = ('B' << 8) | 'M'; #else UINT16 bfType = ('M' << 8) | 'B'; #endif UINT32 bfSize = swap32(bfHeaderSize + biHeaderSize + sizeof(UINT32) + imageSize); UINT16 bfReserved1 = 0; UINT16 bfReserved2 = 0; UINT32 bfOffBits = swap32(bfHeaderSize + biHeaderSize + sizeof(UINT32)); UINT32 biSize = swap32(biHeaderSize); UINT32 biWidth = swap32(w); UINT32 biHeight = swap32(h); UINT16 biPlanes = swap16(1); UINT16 biBitCount = swap16(24); UINT32 biCompression = 0; UINT32 biSizeImage = 0; UINT32 biXPelsPerMeter = 0; UINT32 biYPelsPerMeter = 0; UINT32 biClrUsed = 0; UINT32 biClrImportant = 0; UINT32 rgbquad = 0; icon.SetAttribute(URL::KForceContentType, URL_BMP_CONTENT); icon.ForceStatus(URL_LOADING); icon.WriteDocumentData(URL::KNormal, (const char *) &bfType, sizeof(bfType)); icon.WriteDocumentData(URL::KNormal, (const char *) &bfSize, sizeof(bfSize)); icon.WriteDocumentData(URL::KNormal, (const char *) &bfReserved1, sizeof(bfReserved1)); icon.WriteDocumentData(URL::KNormal, (const char *) &bfReserved2, sizeof(bfReserved2)); icon.WriteDocumentData(URL::KNormal, (const char *) &bfOffBits, sizeof(bfOffBits)); icon.WriteDocumentData(URL::KNormal, (const char *) &biSize, sizeof(biSize)); icon.WriteDocumentData(URL::KNormal, (const char *) &biWidth, sizeof(biWidth)); icon.WriteDocumentData(URL::KNormal, (const char *) &biHeight, sizeof(biHeight)); icon.WriteDocumentData(URL::KNormal, (const char *) &biPlanes, sizeof(biPlanes)); icon.WriteDocumentData(URL::KNormal, (const char *) &biBitCount, sizeof(biBitCount)); icon.WriteDocumentData(URL::KNormal, (const char *) &biCompression, sizeof(biCompression)); icon.WriteDocumentData(URL::KNormal, (const char *) &biSizeImage, sizeof(biSizeImage)); icon.WriteDocumentData(URL::KNormal, (const char *) &biXPelsPerMeter, sizeof(biXPelsPerMeter)); icon.WriteDocumentData(URL::KNormal, (const char *) &biYPelsPerMeter, sizeof(biYPelsPerMeter)); icon.WriteDocumentData(URL::KNormal, (const char *) &biClrUsed, sizeof(biClrUsed)); icon.WriteDocumentData(URL::KNormal, (const char *) &biClrImportant, sizeof(biClrImportant)); icon.WriteDocumentData(URL::KNormal, (const char *) &rgbquad, sizeof(rgbquad)); unsigned char *data = new unsigned char[4*w]; for(int i=0; i<h; i++) { memset(data,0,4*w); bmp->GetLineData(data,h-i-1); for(int j=0; j<w; j++) { unsigned char *color = data + 4*j; #ifdef OPERA_BIG_ENDIAN unsigned char r = color[3]; unsigned char g = color[2]; unsigned char b = color[1]; unsigned char a = color[0]; #else unsigned char r = color[0]; unsigned char g = color[1]; unsigned char b = color[2]; unsigned char a = color[3]; #endif // assume white background r = (a*r + (255-a)*255) / 255; g = (a*g + (255-a)*255) / 255; b = (a*b + (255-a)*255) / 255; icon.WriteDocumentData(URL::KNormal, (const char *) &r, sizeof(r)); icon.WriteDocumentData(URL::KNormal, (const char *) &g, sizeof(g)); icon.WriteDocumentData(URL::KNormal, (const char *) &b, sizeof(b)); } } delete [] data; icon.WriteDocumentDataFinished(); icon.ForceStatus(URL_LOADED); return icon; }