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