Esempio n. 1
0
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;
}