sbImageTools.cpp
Go to the documentation of this file.
1 /*
2  *=BEGIN SONGBIRD GPL
3  *
4  * This file is part of the Songbird web player.
5  *
6  * Copyright(c) 2005-2009 POTI, Inc.
7  * http://www.songbirdnest.com
8  *
9  * This file may be licensed under the terms of of the
10  * GNU General Public License Version 2 (the ``GPL'').
11  *
12  * Software distributed under the License is distributed
13  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
14  * express or implied. See the GPL for the specific language
15  * governing rights and limitations.
16  *
17  * You should have received a copy of the GPL along with this
18  * program. If not, go to http://www.gnu.org/licenses/gpl.html
19  * or write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  *=END SONGBIRD GPL
23  */
24 
25 #include "sbImageTools.h"
26 
27 #include <nsIInputStream.h>
28 
29 #include <nsCOMPtr.h>
30 #include <nsComponentManagerUtils.h>
31 #include <nsWeakReference.h>
32 
33 #include <imgIContainer.h>
34 #include <imgIDecoder.h>
35 #include <imgIDecoderObserver.h>
36 #include <imgILoad.h>
37 
38 class HelperLoader : public imgILoad,
39  public imgIDecoderObserver,
40  public nsSupportsWeakReference
41 {
42  public:
44  NS_DECL_IMGILOAD
45  NS_DECL_IMGIDECODEROBSERVER
46  NS_DECL_IMGICONTAINEROBSERVER
47  HelperLoader(void);
48 
49  private:
50  nsCOMPtr<imgIContainer> mContainer;
51 };
52 
53 NS_IMPL_ISUPPORTS4 (HelperLoader, imgILoad, imgIDecoderObserver, imgIContainerObserver, nsISupportsWeakReference)
54 
56 {
57 }
58 
59 /* Implement imgILoad::image getter */
60 NS_IMETHODIMP
61 HelperLoader::GetImage(imgIContainer **aImage)
62 {
63  NS_ENSURE_ARG_POINTER(aImage);
64 
65  *aImage = mContainer;
66  NS_IF_ADDREF (*aImage);
67  return NS_OK;
68 }
69 
70 /* Implement imgILoad::image setter */
71 NS_IMETHODIMP
72 HelperLoader::SetImage(imgIContainer *aImage)
73 {
74  mContainer = aImage;
75  return NS_OK;
76 }
77 
78 /* Implement imgILoad::isMultiPartChannel getter */
79 NS_IMETHODIMP
80 HelperLoader::GetIsMultiPartChannel(PRBool *aIsMultiPartChannel)
81 {
82  NS_ENSURE_ARG_POINTER(aIsMultiPartChannel);
83 
84  *aIsMultiPartChannel = PR_FALSE;
85  return NS_OK;
86 }
87 
88 /* Implement imgIDecoderObserver::onStartRequest() */
89 NS_IMETHODIMP
90 HelperLoader::OnStartRequest(imgIRequest *aRequest)
91 {
92  return NS_OK;
93 }
94 
95 /* Implement imgIDecoderObserver::onStartDecode() */
96 NS_IMETHODIMP
97 HelperLoader::OnStartDecode(imgIRequest *aRequest)
98 {
99  return NS_OK;
100 }
101 
102 /* Implement imgIDecoderObserver::onStartContainer() */
103 NS_IMETHODIMP
104 HelperLoader::OnStartContainer(imgIRequest *aRequest, imgIContainer
105 *aContainer)
106 {
107  return NS_OK;
108 }
109 
110 /* Implement imgIDecoderObserver::onStartFrame() */
111 NS_IMETHODIMP
112 HelperLoader::OnStartFrame(imgIRequest *aRequest, PRUint32 aFrame)
113 {
114  return NS_OK;
115 }
116 
117 /* Implement imgIDecoderObserver::onDataAvailable() */
118 NS_IMETHODIMP
119 HelperLoader::OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
120  const nsIntRect * aRect)
121 {
122  return NS_OK;
123 }
124 
125 /* Implement imgIDecoderObserver::onStopFrame() */
126 NS_IMETHODIMP
127 HelperLoader::OnStopFrame(imgIRequest *aRequest, PRUint32 aFrame)
128 {
129  return NS_OK;
130 }
131 
132 /* Implement imgIDecoderObserver::onStopContainer() */
133 NS_IMETHODIMP
134 HelperLoader::OnStopContainer(imgIRequest *aRequest, imgIContainer
135 *aContainer)
136 {
137  return NS_OK;
138 }
139 
140 /* Implement imgIDecoderObserver::onStopDecode() */
141 NS_IMETHODIMP
142 HelperLoader::OnStopDecode(imgIRequest *aRequest, nsresult status, const
143 PRUnichar *statusArg)
144 {
145  return NS_OK;
146 }
147 
148 /* Implement imgIDecoderObserver::onStopRequest() */
149 NS_IMETHODIMP
150 HelperLoader::OnStopRequest(imgIRequest *aRequest, PRBool aIsLastPart)
151 {
152  return NS_OK;
153 }
154 
155 /* implement imgIContainerObserver::frameChanged() */
156 NS_IMETHODIMP
157 HelperLoader::FrameChanged(imgIContainer *aContainer,
158  nsIntRect * aDirtyRect)
159 {
160  return NS_OK;
161 }
162 
163 /* Just like imgITools::DecodeImageData(), but with workarounds for
164  bugs in mozilla components */
165 /* static */ nsresult
166 sbImageTools::DecodeImageData(nsIInputStream* aInStr,
167  const nsACString& aMimeType,
168  imgIContainer **aContainer)
169 {
170  NS_ENSURE_ARG_POINTER(aContainer);
171  NS_ENSURE_ARG_POINTER(aInStr);
172 
173  nsresult rv;
174  // Get an image decoder for our media type
175  nsCString decoderCID = NS_LITERAL_CSTRING("@mozilla.org/image/decoder;2?type=");
176  decoderCID.Append(aMimeType);
177 
178  nsCOMPtr<imgIDecoder> decoder = do_CreateInstance(decoderCID.get());
179  if (!decoder)
180  return NS_ERROR_NOT_AVAILABLE;
181 
182  // Init the decoder, we use a small utility class here.
183  nsCOMPtr<imgILoad> loader = new HelperLoader();
184  if (!loader)
185  return NS_ERROR_OUT_OF_MEMORY;
186 
187  // If caller provided an existing container, use it.
188  if (*aContainer)
189  loader->SetImage(*aContainer);
190 
191  rv = decoder->Init(loader);
192  NS_ENSURE_SUCCESS(rv, rv);
193 
194  PRUint32 length;
195  rv = aInStr->Available(&length);
196  NS_ENSURE_SUCCESS(rv, rv);
197 
198  PRUint32 written;
199  NS_ENSURE_SUCCESS(rv, rv);
200  rv = decoder->WriteFrom(aInStr, length, &written);
201  NS_ENSURE_SUCCESS(rv, rv);
202  if (written != length)
203  NS_WARNING("decoder didn't eat all of its vegetables");
204  rv = decoder->Flush();
205  /* Some decoders don't implement Flush, but that's ok for those decoders... */
206  if (rv != NS_ERROR_NOT_IMPLEMENTED) {
207  NS_ENSURE_SUCCESS(rv, rv);
208  }
209  rv = decoder->Close();
210  NS_ENSURE_SUCCESS(rv, rv);
211 
212  // If caller didn't provide an existing container, return the new one.
213  if (!*aContainer)
214  loader->GetImage(aContainer);
215 
216  return NS_OK;
217 
218 }
219 
NS_IMPL_ISUPPORTS4(sbDownloadDevice, nsIObserver, sbIDeviceBase, sbIDownloadDevice, sbIMediaListListener) sbDownloadDevice
return NS_OK
NS_DECL_ISUPPORTS NS_DECL_IMGILOAD NS_DECL_IMGIDECODEROBSERVER NS_DECL_IMGICONTAINEROBSERVER HelperLoader(void)
static nsresult DecodeImageData(nsIInputStream *aInStr, const nsACString &aMimeType, imgIContainer **aContainer)