32 #include <nsIIOService.h> 
   34 #include <nsIResProtocolHandler.h> 
   35 #include <nsIFileProtocolHandler.h> 
   36 #include <nsIMIMEService.h> 
   37 #include <nsIProtocolHandler.h> 
   38 #include <nsIBufferedStreams.h> 
   40 #include <nsIMutableArray.h> 
   41 #include <nsIFileStreams.h> 
   42 #include <nsISeekableStream.h> 
   43 #include <nsIBinaryInputStream.h> 
   45 #include <imgITools.h> 
   46 #include <imgIEncoder.h> 
   47 #include <nsComponentManagerUtils.h> 
   49 #include <nsThreadUtils.h> 
   56 #include <sbIJobProgress.h> 
   57 #include <sbIFileMetadataService.h> 
   58 #include <sbIAlbumArtService.h> 
   62 #define BUFFER_CHUNK_SIZE 1024  
   68     : mHasAlbumArt(PR_FALSE),
 
   81   NS_ENSURE_ARG_POINTER (aItem);
 
   82   NS_ENSURE_ARG_POINTER (aImageFormats);
 
   88   mImageFormats = aImageFormats;
 
   93   if (NS_FAILED (rv) || imageSpec.IsEmpty()) {
 
   94     mHasAlbumArt = PR_FALSE;
 
   98   nsCOMPtr<nsIIOService> ioservice =
 
  100   NS_ENSURE_SUCCESS(rv, rv);
 
  102   cImageSpec = NS_LossyConvertUTF16toASCII(imageSpec);
 
  103   nsCOMPtr<nsIURI> imageURI;
 
  104   rv = ioservice->NewURI(cImageSpec, nsnull, nsnull,
 
  105           getter_AddRefs(imageURI));
 
  106   NS_ENSURE_SUCCESS(rv, rv);
 
  108   nsCOMPtr<nsIThread> 
target;
 
  109   rv = NS_GetMainThread(getter_AddRefs(target));
 
  110   NS_ENSURE_SUCCESS(rv, rv);
 
  112   nsCOMPtr<nsIURI> proxiedURI;
 
  116                             NS_PROXY_SYNC | NS_PROXY_ALWAYS,
 
  117                             getter_AddRefs(proxiedURI));
 
  118   NS_ENSURE_SUCCESS(rv, rv);
 
  121   rv = proxiedURI->SchemeIs(
"resource", &isResource);
 
  122   NS_ENSURE_SUCCESS(rv, rv);
 
  125     nsCOMPtr<nsIProtocolHandler> resHandler;
 
  126     rv = ioservice->GetProtocolHandler(
"resource", getter_AddRefs(resHandler));
 
  127     NS_ENSURE_SUCCESS(rv, rv);
 
  129     nsCOMPtr<nsIResProtocolHandler> proxiedResourceProtocolHandler;
 
  131                               NS_GET_IID(nsIResProtocolHandler),
 
  133                               NS_PROXY_SYNC | NS_PROXY_ALWAYS,
 
  134                               getter_AddRefs(proxiedResourceProtocolHandler));
 
  135     NS_ENSURE_SUCCESS(rv, rv);
 
  137     rv = proxiedResourceProtocolHandler->ResolveURI(imageURI, cImageSpec);
 
  138     NS_ENSURE_SUCCESS(rv, rv);
 
  141   nsCOMPtr<nsIProtocolHandler> fileHandler;
 
  142   rv = ioservice->GetProtocolHandler(
"file", getter_AddRefs(fileHandler));
 
  143   NS_ENSURE_SUCCESS(rv, rv);
 
  145   nsCOMPtr<nsIFileProtocolHandler> proxiedFileProtocolHandler;
 
  147                             NS_GET_IID(nsIFileProtocolHandler),
 
  149                             NS_PROXY_SYNC | NS_PROXY_ALWAYS,
 
  150                             getter_AddRefs(proxiedFileProtocolHandler));
 
  151   NS_ENSURE_SUCCESS(rv, rv);
 
  153   nsCOMPtr<nsIFile> imageFile;
 
  154   rv = proxiedFileProtocolHandler->GetFileFromURLSpec(cImageSpec,
 
  155           getter_AddRefs(imageFile));
 
  156   NS_ENSURE_SUCCESS(rv, rv);
 
  158   nsCOMPtr<nsIMIMEService> mimeService =
 
  160   NS_ENSURE_SUCCESS(rv, rv);
 
  161   rv = mimeService->GetTypeFromFile(imageFile, mImageMimeType);
 
  162   NS_ENSURE_SUCCESS(rv, rv);
 
  165   mInputStream = do_CreateInstance(
 
  166       "@mozilla.org/network/file-input-stream;1", &rv);
 
  167   NS_ENSURE_SUCCESS(rv, rv);
 
  169   rv = mInputStream->Init(imageFile, 
PR_RDONLY, 0, 0);
 
  170   NS_ENSURE_SUCCESS(rv, rv);
 
  172   nsCOMPtr<nsIBufferedInputStream> bufferedInputStream =
 
  173       do_CreateInstance(
"@mozilla.org/network/buffered-input-stream;1", &rv);
 
  174   NS_ENSURE_SUCCESS(rv, rv);
 
  177   NS_ENSURE_SUCCESS(rv, rv);
 
  181                                      getter_AddRefs(mImgContainer));
 
  182   NS_ENSURE_SUCCESS(rv, rv);
 
  184   rv = mImgContainer->GetHeight(&mImageHeight);
 
  185   NS_ENSURE_SUCCESS(rv, rv);
 
  187   rv = mImgContainer->GetWidth(&mImageWidth);
 
  188   NS_ENSURE_SUCCESS(rv, rv);
 
  190   mHasAlbumArt = PR_TRUE;
 
  193   nsCOMPtr<nsISeekableStream> seekableStream =
 
  194       do_QueryInterface(mInputStream, &rv);
 
  195   NS_ENSURE_SUCCESS(rv, rv);
 
  196   rv = seekableStream->Seek(nsISeekableStream::NS_SEEK_SET, 0);
 
  197   NS_ENSURE_SUCCESS(rv, rv);
 
  206   NS_ENSURE_ARG_POINTER (aRange);
 
  207   NS_ENSURE_ARG_POINTER (aVal);
 
  208   NS_ENSURE_ARG_POINTER (aIsValid);
 
  213   rv = aRange->GetValueCount(&valueCount);
 
  214   NS_ENSURE_SUCCESS (rv, rv);
 
  216   if (valueCount == 0) {
 
  217     PRInt32 
min, max, step;
 
  218     rv = aRange->GetMin(&min);
 
  219     NS_ENSURE_SUCCESS (rv, rv);
 
  220     rv = aRange->GetMax(&max);
 
  221     NS_ENSURE_SUCCESS (rv, rv);
 
  222     rv = aRange->GetStep(&step);
 
  223     NS_ENSURE_SUCCESS (rv, rv);
 
  225     if (min <= aVal && max >= aVal && (step == 0 || aVal % step == 0)) {
 
  229       *aIsValid = PR_FALSE;
 
  234   for (PRUint32 
i = 0; 
i < valueCount; 
i++) {
 
  237     NS_ENSURE_SUCCESS (rv, rv);
 
  245   *aIsValid = PR_FALSE;
 
  253   NS_ENSURE_ARG_POINTER (aFormat);
 
  254   NS_ENSURE_ARG_POINTER (aIsValid);
 
  257   nsCOMPtr<sbIDevCapRange> widthRange;
 
  258   nsCOMPtr<sbIDevCapRange> heightRange;
 
  260   rv = aFormat->GetSupportedWidths(getter_AddRefs(widthRange));
 
  261   if (NS_SUCCEEDED (rv) && widthRange) {
 
  262     rv = aFormat->GetSupportedHeights(getter_AddRefs(heightRange));
 
  263     if (NS_SUCCEEDED (rv) && heightRange) {
 
  265       PRBool validWidth, validHeight;
 
  267       NS_ENSURE_SUCCESS (rv, rv);
 
  270       NS_ENSURE_SUCCESS (rv, rv);
 
  272       if (validWidth && validHeight) {
 
  280   nsCOMPtr<nsIArray> explicitSizes;
 
  281   rv = aFormat->GetSupportedExplicitSizes(getter_AddRefs(explicitSizes));
 
  282   NS_ENSURE_SUCCESS (rv, rv);
 
  285   rv = explicitSizes->GetLength(&numSizes);
 
  286   NS_ENSURE_SUCCESS (rv, rv);
 
  288   for (PRUint32 
i = 0; 
i < numSizes; 
i++) {
 
  289     nsCOMPtr<sbIImageSize> size;
 
  290     rv = explicitSizes->QueryElementAt(
i, NS_GET_IID(
sbIImageSize),
 
  291             getter_AddRefs(size));
 
  292     NS_ENSURE_SUCCESS (rv, rv);
 
  295     rv = size->GetWidth(&width);
 
  296     NS_ENSURE_SUCCESS (rv, rv);
 
  297     rv = size->GetHeight(&height);
 
  298     NS_ENSURE_SUCCESS (rv, rv);
 
  300     if (mImageWidth == width && mImageHeight == height) {
 
  306   *aIsValid = PR_FALSE;
 
  311 sbTranscodeAlbumArt::GetNeedsAlbumArtConversion(PRBool *aNeedsConversion)
 
  313   NS_ENSURE_ARG_POINTER (aNeedsConversion);
 
  314   NS_ENSURE_STATE (mImageFormats);
 
  319     *aNeedsConversion = PR_FALSE;
 
  323   PRUint32 numFormats = 0;
 
  324   rv = mImageFormats->GetLength(&numFormats);
 
  325   NS_ENSURE_SUCCESS (rv, rv);
 
  331   if (numFormats == 0) {
 
  332     *aNeedsConversion = PR_FALSE;
 
  336   for (PRUint32 
i = 0; 
i < numFormats; 
i++) {
 
  337     nsCOMPtr<sbIImageFormatType> format;
 
  339             getter_AddRefs(format));
 
  340     NS_ENSURE_SUCCESS (rv, rv);
 
  342     nsCString formatMimeType;
 
  343     rv = format->GetImageFormat(formatMimeType);
 
  344     NS_ENSURE_SUCCESS (rv, rv);
 
  346     if (formatMimeType == mImageMimeType) {
 
  350       NS_ENSURE_SUCCESS (rv, rv);
 
  353         *aNeedsConversion = PR_FALSE;
 
  359   *aNeedsConversion = PR_TRUE;
 
  366   nsCString encoderCID = NS_LITERAL_CSTRING(
 
  367           "@mozilla.org/image/encoder;2?type=");
 
  368   encoderCID.Append(mimeType);
 
  370   nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(encoderCID.get(), &rv);
 
  371   if (NS_SUCCEEDED(rv)) {
 
  372     *haveEncoder = PR_TRUE;
 
  375     *haveEncoder = PR_FALSE;
 
  385   NS_ENSURE_ARG_POINTER (aWidth);
 
  386   NS_ENSURE_ARG_POINTER (aHeight);
 
  387   NS_ENSURE_STATE (mImageFormats);
 
  405   PRUint32 numFormats = 0;
 
  406   rv = mImageFormats->GetLength(&numFormats);
 
  407   NS_ENSURE_SUCCESS (rv, rv);
 
  408   for (PRUint32 
i = 0; 
i < numFormats; 
i++) {
 
  409     nsCOMPtr<sbIImageFormatType> format;
 
  411                                        getter_AddRefs(format));
 
  412     NS_ENSURE_SUCCESS (rv, rv);
 
  414     nsCString formatMimeType;
 
  415     rv = format->GetImageFormat(formatMimeType);
 
  416     NS_ENSURE_SUCCESS (rv, rv);
 
  420     NS_ENSURE_SUCCESS(rv, rv);
 
  429     NS_ENSURE_SUCCESS (rv, rv);
 
  432       aMimeType = formatMimeType;
 
  433       *aWidth = mImageWidth;
 
  434       *aHeight = mImageHeight;
 
  440   nsCOMPtr<sbIImageFormatType> chosenformat;
 
  441   for (PRUint32 
i = 0; 
i < numFormats; 
i++) {
 
  442     nsCOMPtr<sbIImageFormatType> format;
 
  444             getter_AddRefs(format));
 
  445     NS_ENSURE_SUCCESS (rv, rv);
 
  447     nsCString formatMimeType;
 
  448     rv = format->GetImageFormat(formatMimeType);
 
  449     NS_ENSURE_SUCCESS (rv, rv);
 
  453     NS_ENSURE_SUCCESS(rv, rv);
 
  456       chosenformat = format;
 
  462     return NS_ERROR_FAILURE;
 
  464   nsCOMPtr<nsIArray> explicitSizes;
 
  465   rv = chosenformat->GetSupportedExplicitSizes(getter_AddRefs(explicitSizes));
 
  466   NS_ENSURE_SUCCESS (rv, rv);
 
  468   rv = chosenformat->GetImageFormat(aMimeType);
 
  469   NS_ENSURE_SUCCESS (rv, rv);
 
  471   PRInt32 bestWidth = 0;
 
  472   PRInt32 bestHeight = 0;
 
  473   PRInt32 bestSmallerWidth = 0;
 
  474   PRInt32 bestSmallerHeight = 0;
 
  476   PRUint32 numSizes = 0;
 
  477   rv = explicitSizes->GetLength(&numSizes);
 
  478   NS_ENSURE_SUCCESS (rv, rv);
 
  479   for (PRUint32 
i = 0; 
i < numSizes; 
i++) {
 
  480     nsCOMPtr<sbIImageSize> size;
 
  481     rv = explicitSizes->QueryElementAt(
i, NS_GET_IID(
sbIImageSize),
 
  482                                        getter_AddRefs(size));
 
  483     NS_ENSURE_SUCCESS (rv, rv);
 
  486     rv = size->GetWidth(&width);
 
  487     NS_ENSURE_SUCCESS (rv, rv);
 
  488     rv = size->GetHeight(&height);
 
  489     NS_ENSURE_SUCCESS (rv, rv);
 
  491     if (width >= mImageWidth && height >= mImageHeight &&
 
  492         (bestWidth == 0 || bestHeight == 0 || 
 
  493          width < bestWidth || height < bestHeight))
 
  498     else if (width < mImageWidth && height < mImageHeight &&
 
  499              (width > bestSmallerWidth || height > bestSmallerHeight))
 
  501       bestSmallerWidth = 
width;
 
  502       bestSmallerHeight = 
height;
 
  506   if (bestWidth && bestHeight) {
 
  508     *aHeight = bestHeight;
 
  511   else if (bestSmallerWidth && bestSmallerHeight) {
 
  512     *aWidth = bestSmallerWidth;
 
  513     *aHeight = bestSmallerHeight;
 
  517     return NS_ERROR_FAILURE;
 
  524   NS_ENSURE_ARG_POINTER(aImageStream);
 
  526   PRBool needsConversion = PR_FALSE;
 
  527   nsresult rv = GetNeedsAlbumArtConversion(&needsConversion);
 
  528   NS_ENSURE_SUCCESS(rv, rv);
 
  529   if (needsConversion) {
 
  535     NS_ENSURE_SUCCESS (rv, rv);
 
  538             "@mozilla.org/image/tools;1", &rv);
 
  539     NS_ENSURE_SUCCESS(rv, rv);
 
  541     rv = imgTools->EncodeScaledImage(mImgContainer, mimeType, width, height,
 
  543     NS_ENSURE_SUCCESS(rv, rv);
 
  548     NS_IF_ADDREF(*aImageStream = mInputStream);
 
  556   NS_ENSURE_STATE (mImageFormats);
 
  557   NS_ENSURE_STATE (mItem);
 
  559   NS_ASSERTION(!NS_IsMainThread(),
 
  560           "ConvertArt must not be called from the main thread");
 
  567   NS_ENSURE_SUCCESS (rv, rv);
 
  570           "@mozilla.org/image/tools;1", &rv);
 
  571   NS_ENSURE_SUCCESS(rv, rv);
 
  573   nsCOMPtr<nsIInputStream> imageStream;
 
  574   rv = imgTools->EncodeScaledImage(mImgContainer, mimeType, width, height,
 
  575           getter_AddRefs(imageStream));
 
  576   NS_ENSURE_SUCCESS(rv, rv);
 
  578   nsCOMPtr<nsIBinaryInputStream> binaryStream =
 
  579              do_CreateInstance(
"@mozilla.org/binaryinputstream;1", &rv);
 
  580   NS_ENSURE_SUCCESS(rv, rv);
 
  582   rv = binaryStream->SetInputStream(imageStream);
 
  583   NS_ENSURE_SUCCESS(rv, rv);
 
  585   PRUint32 imageDataLen;
 
  586   rv = imageStream->Available(&imageDataLen);
 
  587   NS_ENSURE_SUCCESS(rv, rv);
 
  590   rv = binaryStream->ReadByteArray(imageDataLen, &imageData);
 
  591   NS_ENSURE_SUCCESS(rv, rv);
 
  597   NS_ENSURE_SUCCESS(rv, rv);
 
  599   nsCOMPtr<nsIURI> cacheURI;
 
  600   rv = albumArtService->CacheImage(mimeType,
 
  603                                    getter_AddRefs(cacheURI));
 
  604   NS_ENSURE_SUCCESS(rv, rv);
 
  606   nsCString imageURISpec;
 
  607   rv = cacheURI->GetSpec(imageURISpec);
 
  608   NS_ENSURE_SUCCESS(rv, rv);
 
  611                           NS_ConvertUTF8toUTF16(imageURISpec));
 
  612   NS_ENSURE_SUCCESS(rv, rv);
 
  618   nsCOMPtr<nsIMutableArray> mediaItemArray =
 
  619       do_CreateInstance(
"@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
 
  620   NS_ENSURE_SUCCESS(rv, rv);
 
  622   rv = mediaItemArray->AppendElement(mItem, PR_FALSE);
 
  623   NS_ENSURE_SUCCESS(rv, rv);
 
  625   nsTArray<nsString> propArray;
 
  626   NS_ENSURE_TRUE(propArray.AppendElement(
 
  628           NS_ERROR_OUT_OF_MEMORY);
 
  630   nsCOMPtr<nsIStringEnumerator> propsToWrite =
 
  632   NS_ENSURE_TRUE(propsToWrite, NS_ERROR_OUT_OF_MEMORY);
 
  635      "@songbirdnest.com/Songbird/FileMetadataService;1", &rv);
 
  636   NS_ENSURE_SUCCESS(rv, rv);
 
  638   nsCOMPtr<sbIJobProgress> job;
 
  639   rv = metadataService->Write(mediaItemArray, propsToWrite,
 
  640           getter_AddRefs(job));
 
  641   NS_ENSURE_SUCCESS(rv, rv);
 
  645   nsCOMPtr<nsIThread> 
target;
 
  646   rv = NS_GetMainThread(getter_AddRefs(target));
 
  647   NS_ENSURE_SUCCESS(rv, rv);
 
  649   nsCOMPtr<sbIJobProgress> proxiedJob;
 
  653                             NS_PROXY_SYNC | NS_PROXY_ALWAYS,
 
  654                             getter_AddRefs(proxiedJob));
 
  655   NS_ENSURE_SUCCESS(rv, rv);
 
  660   PRBool isRunning = PR_TRUE;
 
  664     rv = proxiedJob->GetStatus(&status);
 
  665     NS_ENSURE_SUCCESS(rv, rv);
 
  670       PR_Sleep(PR_MillisecondsToInterval(100));
 
  672       return NS_ERROR_FAILURE;
 
NS_IMPL_THREADSAFE_ISUPPORTS1(sbTranscodeAlbumArt, sbITranscodeAlbumArt) sbTranscodeAlbumArt
#define SB_ALBUMARTSERVICE_CONTRACTID
void GetTargetFormat(out AUTF8String mimeType, out long width, out long height)
Generic interface for exposing long running jobs to the UI. 
virtual ~sbTranscodeAlbumArt()
nsresult IsValidSizeForFormat(sbIImageFormatType *aFormat, PRBool *aIsValid)
nsresult IsValidSizeForRange(sbIDevCapRange *aRange, PRInt32 aVal, PRBool *aIsValid)
void Init(in sbIMediaItem aItem, in nsIArray aSupportedFormats)
nsresult do_GetProxyForObject(nsIEventTarget *aTarget, REFNSIID aIID, nsISupports *aObj, PRInt32 aProxyType, void **aProxyObject)
nsIInputStream GetTranscodedArt()
restoreDimensions aHeight
const unsigned short STATUS_RUNNING
Constant indicating that the job is active. 
const sbCreateProxiedComponent do_ProxiedGetService(const nsCID &aCID, nsresult *error=0)
#define BUFFER_CHUNK_SIZE
static nsresult HaveEncoderForFormat(nsCString mimeType, PRBool *haveEncoder)
this _dialogInput val(dateText)
long GetValue(in unsigned long aIndex)
const unsigned short STATUS_FAILED
Constant indicating that the job has completed with errors. 
_getSelectedPageStyle s i
#define SB_PROPERTY_PRIMARYIMAGEURL