static void writeImageToDataObject(DataObject* dataObject, Element* element, const KURL& url) { // Shove image data into a DataObject for use as a file ImageResource* cachedImage = getImageResource(element); if (!cachedImage || !cachedImage->imageForLayoutObject(element->layoutObject()) || !cachedImage->isLoaded()) return; SharedBuffer* imageBuffer = cachedImage->imageForLayoutObject(element->layoutObject())->data(); if (!imageBuffer || !imageBuffer->size()) return; String imageExtension = cachedImage->image()->filenameExtension(); ASSERT(!imageExtension.isEmpty()); // Determine the filename for the file contents of the image. String filename = cachedImage->response().suggestedFilename(); if (filename.isEmpty()) filename = url.lastPathComponent(); String fileExtension; if (filename.isEmpty()) { filename = element->getAttribute(HTMLNames::altAttr); } else { // Strip any existing extension. Assume that alt text is usually not a filename. int extensionIndex = filename.reverseFind('.'); if (extensionIndex != -1) { fileExtension = filename.substring(extensionIndex + 1); filename.truncate(extensionIndex); } } if (!fileExtension.isEmpty() && fileExtension != imageExtension) { String imageMimeType = MIMETypeRegistry::getMIMETypeForExtension(imageExtension); ASSERT(imageMimeType.startsWith("image/")); // Use the file extension only if it has imageMimeType: it's untrustworthy otherwise. if (imageMimeType == MIMETypeRegistry::getMIMETypeForExtension(fileExtension)) imageExtension = fileExtension; } imageExtension = "." + imageExtension; validateFilename(filename, imageExtension); dataObject->addSharedBuffer(filename + imageExtension, imageBuffer); }
void ImageLoader::LoadHardcodedGfx(const std::unordered_map<std::wstring, ResourceFileInfo>* fileData, const std::unordered_map<std::wstring, ResourceFileInfo>* oldFileData) { for (int idx1 = 1; idx1 <= HardcodedGraphicsItem::Size(); idx1++) { HardcodedGraphicsItem& hItemInfo = HardcodedGraphicsItem::Get(idx1); // No processing invalid or mask items here if ((hItemInfo.state != HardcodedGraphicsItem::HITEMSTATE_NORMAL) && (hItemInfo.state != HardcodedGraphicsItem::HITEMSTATE_ARRAY)) continue; int minItem = hItemInfo.isArray() ? hItemInfo.minItem : -1; int maxItem = hItemInfo.isArray() ? hItemInfo.maxItem : -1; for (int idx2 = minItem; idx2 <= maxItem; idx2++) { if (hItemInfo.isArray() && !hItemInfo.isValidArrayIndex(idx2)) { // If this index isn't valid, skip it continue; } HDC colorHDC = nullptr; HDC maskHDC = nullptr; hItemInfo.getHDC(idx2, &colorHDC, &maskHDC); if (colorHDC == nullptr) { // No such thing as mask-only graphics continue; } std::wstring hardcodedName = L"hardcoded-" + std::to_wstring(idx1); if (hItemInfo.isArray()) { hardcodedName += L"-" + std::to_wstring(idx2); } // Make note of name to HDC mapping m_NameToHDC[WStr2Str(hardcodedName)] = (uintptr_t)colorHDC; ResourceFileInfo newMain, newMask; ResourceFileInfo oldMain, oldMask; getImageResource(hardcodedName, *fileData, newMain, newMask); if (oldFileData != nullptr) { getImageResource(hardcodedName, *oldFileData, oldMain, oldMask); } // If anything has changed, reload if ((oldFileData == nullptr) || (newMain != oldMain) || (newMask != oldMask)) { std::shared_ptr<LunaImage> img = nullptr; std::shared_ptr<LunaImage> mask = nullptr; if (newMain.done) { // If we found a file, load from it img = LunaImage::fromFile(newMain.path.c_str(), &newMain); mask = LunaImage::fromFile(newMask.path.c_str(), &newMask); } else { // Otherwise, load from HDC img = LunaImage::fromHDC(colorHDC); mask = LunaImage::fromHDC(maskHDC); // TODO: Consider special case for maskless hardcoded graphics from HDC, where black should be made transparent } if (img && mask) { img->setMask(mask); } if (img) { if (colorHDC != nullptr) ImageLoader::m_Gfx[(uintptr_t)colorHDC] = img; if (maskHDC != nullptr) ImageLoader::m_Gfx[(uintptr_t)maskHDC] = img; } } } } }
void ImageLoaderCategory::updateLoadedImages(const std::unordered_map<std::wstring, ResourceFileInfo>* fileData, const std::unordered_map<std::wstring, ResourceFileInfo>* oldFileData) { uint32_t firstIdx = m_Category.getFirstIdx(); uint32_t lastIdx = m_Category.getLastIdx(); std::wstring prefix = m_Category.getPrefix(); for (uint32_t i = firstIdx; i <= lastIdx; i++) { std::wstring imageName = prefix + L"-" + std::to_wstring(i); ResourceFileInfo newMain, newMask; ResourceFileInfo oldMain, oldMask; getImageResource(imageName, *fileData, newMain, newMask); if (oldFileData != nullptr) { getImageResource(imageName, *oldFileData, oldMain, oldMask); } // If anything has changed, reload if ((oldFileData == nullptr) || (newMain != oldMain) || (newMask != oldMask)) { uint32_t width = 0, height = 0; HDC mainImgHdc = nullptr; std::shared_ptr<LunaImage> mainImg = nullptr; if (m_Category.haveImagePtrArray()) { // Make HDC if-needed mainImgHdc = m_Category.getImagePtr(i); if (mainImgHdc == nullptr) { mainImgHdc = CreateCompatibleDC(NULL); m_Category.setImagePtr(i, mainImgHdc); ImageLoader::m_NameToHDC[WStr2Str(imageName)] = (uintptr_t)mainImgHdc; ImageLoader::m_HDCToCategoryAndIndex[(uintptr_t)mainImgHdc] = std::pair<const SMBXImageCategory*, uint32_t>(&m_Category, i); } // Try to load image if (newMain.path.length() > 0) { mainImg = LunaImage::fromFile(newMain.path.c_str(), &newMain); } // Assign image, note size ImageLoader::m_Gfx[(uintptr_t)mainImgHdc] = mainImg; if (mainImg) { if (width < mainImg->getW()) width = mainImg->getW(); if (height < mainImg->getH()) height = mainImg->getH(); } } else { // That's required... throw; } if (m_Category.haveMaskPtrArray() && mainImg) { // Match HDC to non-mask version m_Category.setMaskPtr(i, mainImgHdc); // Try to load image std::shared_ptr<LunaImage> maskImg = nullptr; if (newMask.path.length() > 0) { maskImg = LunaImage::fromFile(newMask.path.c_str(), &newMask); } // Assign image, note size mainImg->setMask(maskImg); if (maskImg) { if (width < maskImg->getW()) width = maskImg->getW(); if (height < maskImg->getH()) height = maskImg->getH(); mainImg->tryMaskToRGBA(); } } m_Category.setWidth(i, (int16_t)min(width, 0x7FFF)); m_Category.setHeight(i, (int16_t)min(height, 0x7FFF)); } } }