1 : /* ***** BEGIN LICENSE BLOCK *****
2 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 : *
4 : * The contents of this file are subject to the Mozilla Public License Version
5 : * 1.1 (the "License"); you may not use this file except in compliance with
6 : * the License. You may obtain a copy of the License at
7 : * http://www.mozilla.org/MPL/
8 : *
9 : * Software distributed under the License is distributed on an "AS IS" basis,
10 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 : * for the specific language governing rights and limitations under the
12 : * License.
13 : *
14 : * The Original Code is an implementation of an icon encoder.
15 : *
16 : * The Initial Developer of the Original Code is
17 : * Mozilla Foundation.
18 : * Portions created by the Initial Developer are Copyright (C) 2011
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : * Brian R. Bondy <netzen@gmail.com>
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either the GNU General Public License Version 2 or later (the "GPL"), or
26 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #include "nsCRT.h"
39 : #include "EndianMacros.h"
40 : #include "nsBMPEncoder.h"
41 : #include "nsPNGEncoder.h"
42 : #include "nsICOEncoder.h"
43 : #include "prmem.h"
44 : #include "prprf.h"
45 : #include "nsString.h"
46 : #include "nsStreamUtils.h"
47 :
48 : using namespace mozilla;
49 : using namespace mozilla::image;
50 :
51 132 : NS_IMPL_THREADSAFE_ISUPPORTS3(nsICOEncoder, imgIEncoder, nsIInputStream, nsIAsyncInputStream)
52 :
53 4 : nsICOEncoder::nsICOEncoder() : mImageBufferStart(nsnull),
54 : mImageBufferCurr(0),
55 : mImageBufferSize(0),
56 : mImageBufferReadPoint(0),
57 : mFinished(false),
58 : mUsePNG(true),
59 4 : mNotifyThreshold(0)
60 : {
61 4 : }
62 :
63 8 : nsICOEncoder::~nsICOEncoder()
64 : {
65 4 : if (mImageBufferStart) {
66 4 : moz_free(mImageBufferStart);
67 4 : mImageBufferStart = nsnull;
68 4 : mImageBufferCurr = nsnull;
69 : }
70 4 : }
71 :
72 : // nsICOEncoder::InitFromData
73 : // Two output options are supported: format=<png|bmp>;bpp=<bpp_value>
74 : // format specifies whether to use png or bitmap format
75 : // bpp specifies the bits per pixel to use where bpp_value can be 24 or 32
76 4 : NS_IMETHODIMP nsICOEncoder::InitFromData(const PRUint8* aData,
77 : PRUint32 aLength,
78 : PRUint32 aWidth,
79 : PRUint32 aHeight,
80 : PRUint32 aStride,
81 : PRUint32 aInputFormat,
82 : const nsAString& aOutputOptions)
83 : {
84 : // validate input format
85 4 : if (aInputFormat != INPUT_FORMAT_RGB &&
86 : aInputFormat != INPUT_FORMAT_RGBA &&
87 : aInputFormat != INPUT_FORMAT_HOSTARGB) {
88 0 : return NS_ERROR_INVALID_ARG;
89 : }
90 :
91 : // Stride is the padded width of each row, so it better be longer
92 4 : if ((aInputFormat == INPUT_FORMAT_RGB &&
93 : aStride < aWidth * 3) ||
94 : ((aInputFormat == INPUT_FORMAT_RGBA || aInputFormat == INPUT_FORMAT_HOSTARGB) &&
95 : aStride < aWidth * 4)) {
96 0 : NS_WARNING("Invalid stride for InitFromData");
97 0 : return NS_ERROR_INVALID_ARG;
98 : }
99 :
100 : nsresult rv;
101 4 : rv = StartImageEncode(aWidth, aHeight, aInputFormat, aOutputOptions);
102 4 : NS_ENSURE_SUCCESS(rv, rv);
103 :
104 : rv = AddImageFrame(aData, aLength, aWidth, aHeight, aStride,
105 4 : aInputFormat, aOutputOptions);
106 4 : NS_ENSURE_SUCCESS(rv, rv);
107 :
108 4 : rv = EndImageEncode();
109 4 : return rv;
110 : }
111 :
112 : // Returns the number of bytes in the image buffer used
113 : // For an ICO file, this is all bytes in the buffer.
114 : NS_IMETHODIMP
115 0 : nsICOEncoder::GetImageBufferUsed(PRUint32 *aOutputSize)
116 : {
117 0 : NS_ENSURE_ARG_POINTER(aOutputSize);
118 0 : *aOutputSize = mImageBufferSize;
119 0 : return NS_OK;
120 : }
121 :
122 : // Returns a pointer to the start of the image buffer
123 : NS_IMETHODIMP
124 0 : nsICOEncoder::GetImageBuffer(char **aOutputBuffer)
125 : {
126 0 : NS_ENSURE_ARG_POINTER(aOutputBuffer);
127 0 : *aOutputBuffer = reinterpret_cast<char*>(mImageBufferStart);
128 0 : return NS_OK;
129 : }
130 :
131 : NS_IMETHODIMP
132 4 : nsICOEncoder::AddImageFrame(const PRUint8* aData,
133 : PRUint32 aLength,
134 : PRUint32 aWidth,
135 : PRUint32 aHeight,
136 : PRUint32 aStride,
137 : PRUint32 aInputFormat,
138 : const nsAString& aFrameOptions)
139 : {
140 4 : if (mUsePNG) {
141 :
142 0 : mContainedEncoder = new nsPNGEncoder();
143 : nsresult rv;
144 0 : nsAutoString noParams;
145 0 : rv = mContainedEncoder->InitFromData(aData, aLength, aWidth, aHeight,
146 0 : aStride, aInputFormat, noParams);
147 0 : NS_ENSURE_SUCCESS(rv, rv);
148 :
149 : PRUint32 PNGImageBufferSize;
150 0 : mContainedEncoder->GetImageBufferUsed(&PNGImageBufferSize);
151 : mImageBufferSize = ICONFILEHEADERSIZE + ICODIRENTRYSIZE +
152 0 : PNGImageBufferSize;
153 0 : mImageBufferStart = static_cast<PRUint8*>(moz_malloc(mImageBufferSize));
154 0 : if (!mImageBufferStart) {
155 0 : return NS_ERROR_OUT_OF_MEMORY;
156 : }
157 0 : mImageBufferCurr = mImageBufferStart;
158 0 : mICODirEntry.mBytesInRes = PNGImageBufferSize;
159 :
160 0 : EncodeFileHeader();
161 0 : EncodeInfoHeader();
162 :
163 : char *imageBuffer;
164 0 : rv = mContainedEncoder->GetImageBuffer(&imageBuffer);
165 0 : NS_ENSURE_SUCCESS(rv, rv);
166 0 : memcpy(mImageBufferCurr, imageBuffer, PNGImageBufferSize);
167 0 : mImageBufferCurr += PNGImageBufferSize;
168 : } else {
169 4 : mContainedEncoder = new nsBMPEncoder();
170 : nsresult rv;
171 :
172 8 : nsAutoString params;
173 4 : params.AppendASCII("bpp=");
174 4 : params.AppendInt(mICODirEntry.mBitCount);
175 :
176 4 : rv = mContainedEncoder->InitFromData(aData, aLength, aWidth, aHeight,
177 4 : aStride, aInputFormat, params);
178 4 : NS_ENSURE_SUCCESS(rv, rv);
179 :
180 4 : PRUint32 andMaskSize = ((GetRealWidth() + 31) / 32) * 4 * // row AND mask
181 4 : GetRealHeight(); // num rows
182 :
183 : PRUint32 BMPImageBufferSize;
184 4 : mContainedEncoder->GetImageBufferUsed(&BMPImageBufferSize);
185 : mImageBufferSize = ICONFILEHEADERSIZE + ICODIRENTRYSIZE +
186 4 : BMPImageBufferSize + andMaskSize;
187 4 : mImageBufferStart = static_cast<PRUint8*>(moz_malloc(mImageBufferSize));
188 4 : if (!mImageBufferStart) {
189 0 : return NS_ERROR_OUT_OF_MEMORY;
190 : }
191 4 : mImageBufferCurr = mImageBufferStart;
192 :
193 : // The icon buffer does not include the BFH at all.
194 4 : mICODirEntry.mBytesInRes = BMPImageBufferSize - BFH_LENGTH + andMaskSize;
195 :
196 : // Encode the icon headers
197 4 : EncodeFileHeader();
198 4 : EncodeInfoHeader();
199 :
200 : char *imageBuffer;
201 4 : rv = mContainedEncoder->GetImageBuffer(&imageBuffer);
202 4 : NS_ENSURE_SUCCESS(rv, rv);
203 : memcpy(mImageBufferCurr, imageBuffer + BFH_LENGTH,
204 4 : BMPImageBufferSize - BFH_LENGTH);
205 : // We need to fix the BMP height to be *2 for the AND mask
206 4 : PRUint32 fixedHeight = GetRealHeight() * 2;
207 4 : fixedHeight = NATIVE32_TO_LITTLE(fixedHeight);
208 : // The height is stored at an offset of 8 from the DIB header
209 4 : memcpy(mImageBufferCurr + 8, &fixedHeight, sizeof(fixedHeight));
210 4 : mImageBufferCurr += BMPImageBufferSize - BFH_LENGTH;
211 :
212 : // Calculate rowsize in DWORD's
213 4 : PRUint32 rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up
214 4 : PRInt32 currentLine = GetRealHeight();
215 :
216 : // Write out the AND mask
217 104 : while (currentLine > 0) {
218 96 : currentLine--;
219 96 : PRUint8* encoded = mImageBufferCurr + currentLine * rowSize;
220 96 : PRUint8* encodedEnd = encoded + rowSize;
221 576 : while (encoded != encodedEnd) {
222 384 : *encoded = 0; // make everything visible
223 384 : encoded++;
224 : }
225 : }
226 :
227 8 : mImageBufferCurr += andMaskSize;
228 : }
229 :
230 4 : return NS_OK;
231 : }
232 :
233 : // See ::InitFromData for other info.
234 4 : NS_IMETHODIMP nsICOEncoder::StartImageEncode(PRUint32 aWidth,
235 : PRUint32 aHeight,
236 : PRUint32 aInputFormat,
237 : const nsAString& aOutputOptions)
238 : {
239 : // can't initialize more than once
240 4 : if (mImageBufferStart || mImageBufferCurr) {
241 0 : return NS_ERROR_ALREADY_INITIALIZED;
242 : }
243 :
244 : // validate input format
245 4 : if (aInputFormat != INPUT_FORMAT_RGB &&
246 : aInputFormat != INPUT_FORMAT_RGBA &&
247 : aInputFormat != INPUT_FORMAT_HOSTARGB) {
248 0 : return NS_ERROR_INVALID_ARG;
249 : }
250 :
251 : // Icons are only 1 byte, so make sure our bitmap is in range
252 4 : if (aWidth > 256 || aHeight > 256) {
253 0 : return NS_ERROR_INVALID_ARG;
254 : }
255 :
256 : // parse and check any provided output options
257 4 : PRUint32 bpp = 24;
258 4 : bool usePNG = true;
259 4 : nsresult rv = ParseOptions(aOutputOptions, &bpp, &usePNG);
260 4 : NS_ENSURE_SUCCESS(rv, rv);
261 :
262 4 : mUsePNG = usePNG;
263 :
264 4 : InitFileHeader();
265 : // The width and height are stored as 0 when we have a value of 256
266 : InitInfoHeader(bpp, aWidth == 256 ? 0 : (PRUint8)aWidth,
267 4 : aHeight == 256 ? 0 : (PRUint8)aHeight);
268 :
269 4 : return NS_OK;
270 : }
271 :
272 4 : NS_IMETHODIMP nsICOEncoder::EndImageEncode()
273 : {
274 : // must be initialized
275 4 : if (!mImageBufferStart || !mImageBufferCurr) {
276 0 : return NS_ERROR_NOT_INITIALIZED;
277 : }
278 :
279 4 : mFinished = true;
280 4 : NotifyListener();
281 :
282 : // if output callback can't get enough memory, it will free our buffer
283 4 : if (!mImageBufferStart || !mImageBufferCurr) {
284 0 : return NS_ERROR_OUT_OF_MEMORY;
285 : }
286 :
287 4 : return NS_OK;
288 : }
289 :
290 : // Parses the encoder options and sets the bits per pixel to use and PNG or BMP
291 : // See InitFromData for a description of the parse options
292 : nsresult
293 4 : nsICOEncoder::ParseOptions(const nsAString& aOptions, PRUint32* bpp,
294 : bool *usePNG)
295 : {
296 : // If no parsing options just use the default of 24BPP and PNG yes
297 4 : if (aOptions.Length() == 0) {
298 0 : if (usePNG) {
299 0 : *usePNG = true;
300 : }
301 0 : if (bpp) {
302 0 : *bpp = 24;
303 : }
304 : }
305 :
306 : // Parse the input string into a set of name/value pairs.
307 : // From format: format=<png|bmp>;bpp=<bpp_value>
308 : // to format: [0] = format=<png|bmp>, [1] = bpp=<bpp_value>
309 8 : nsTArray<nsCString> nameValuePairs;
310 4 : if (!ParseString(NS_ConvertUTF16toUTF8(aOptions), ';', nameValuePairs)) {
311 0 : return NS_ERROR_INVALID_ARG;
312 : }
313 :
314 : // For each name/value pair in the set
315 12 : for (int i = 0; i < nameValuePairs.Length(); ++i) {
316 :
317 : // Split the name value pair [0] = name, [1] = value
318 16 : nsTArray<nsCString> nameValuePair;
319 8 : if (!ParseString(nameValuePairs[i], '=', nameValuePair)) {
320 0 : return NS_ERROR_INVALID_ARG;
321 : }
322 8 : if (nameValuePair.Length() != 2) {
323 0 : return NS_ERROR_INVALID_ARG;
324 : }
325 :
326 : // Parse the format portion of the string format=<png|bmp>;bpp=<bpp_value>
327 8 : if (nameValuePair[0].Equals("format", nsCaseInsensitiveCStringComparator())) {
328 4 : if (nameValuePair[1].Equals("png", nsCaseInsensitiveCStringComparator())) {
329 0 : *usePNG = true;
330 : }
331 4 : else if (nameValuePair[1].Equals("bmp", nsCaseInsensitiveCStringComparator())) {
332 4 : *usePNG = false;
333 : }
334 : else {
335 0 : return NS_ERROR_INVALID_ARG;
336 : }
337 : }
338 :
339 : // Parse the bpp portion of the string format=<png|bmp>;bpp=<bpp_value>
340 8 : if (nameValuePair[0].Equals("bpp", nsCaseInsensitiveCStringComparator())) {
341 4 : if (nameValuePair[1].Equals("24")) {
342 2 : *bpp = 24;
343 : }
344 2 : else if (nameValuePair[1].Equals("32")) {
345 2 : *bpp = 32;
346 : }
347 : else {
348 0 : return NS_ERROR_INVALID_ARG;
349 : }
350 : }
351 : }
352 :
353 4 : return NS_OK;
354 : }
355 :
356 0 : NS_IMETHODIMP nsICOEncoder::Close()
357 : {
358 0 : if (mImageBufferStart) {
359 0 : moz_free(mImageBufferStart);
360 0 : mImageBufferStart = nsnull;
361 0 : mImageBufferSize = 0;
362 0 : mImageBufferReadPoint = 0;
363 0 : mImageBufferCurr = nsnull;
364 : }
365 :
366 0 : return NS_OK;
367 : }
368 :
369 : // Obtains the available bytes to read
370 4 : NS_IMETHODIMP nsICOEncoder::Available(PRUint32 *_retval)
371 : {
372 4 : if (!mImageBufferStart || !mImageBufferCurr) {
373 0 : return NS_BASE_STREAM_CLOSED;
374 : }
375 :
376 4 : *_retval = GetCurrentImageBufferOffset() - mImageBufferReadPoint;
377 4 : return NS_OK;
378 : }
379 :
380 : // [noscript] Reads bytes which are available
381 4 : NS_IMETHODIMP nsICOEncoder::Read(char *aBuf, PRUint32 aCount,
382 : PRUint32 *_retval)
383 : {
384 4 : return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, _retval);
385 : }
386 :
387 : // [noscript] Reads segments
388 4 : NS_IMETHODIMP nsICOEncoder::ReadSegments(nsWriteSegmentFun aWriter,
389 : void *aClosure, PRUint32 aCount,
390 : PRUint32 *_retval)
391 : {
392 4 : PRUint32 maxCount = GetCurrentImageBufferOffset() - mImageBufferReadPoint;
393 4 : if (maxCount == 0) {
394 0 : *_retval = 0;
395 0 : return mFinished ? NS_OK : NS_BASE_STREAM_WOULD_BLOCK;
396 : }
397 :
398 4 : if (aCount > maxCount) {
399 0 : aCount = maxCount;
400 : }
401 :
402 : nsresult rv = aWriter(this, aClosure,
403 : reinterpret_cast<const char*>(mImageBufferStart +
404 : mImageBufferReadPoint),
405 4 : 0, aCount, _retval);
406 4 : if (NS_SUCCEEDED(rv)) {
407 4 : NS_ASSERTION(*_retval <= aCount, "bad write count");
408 4 : mImageBufferReadPoint += *_retval;
409 : }
410 : // errors returned from the writer end here!
411 4 : return NS_OK;
412 : }
413 :
414 : NS_IMETHODIMP
415 0 : nsICOEncoder::IsNonBlocking(bool *_retval)
416 : {
417 0 : *_retval = true;
418 0 : return NS_OK;
419 : }
420 :
421 : NS_IMETHODIMP
422 0 : nsICOEncoder::AsyncWait(nsIInputStreamCallback *aCallback,
423 : PRUint32 aFlags,
424 : PRUint32 aRequestedCount,
425 : nsIEventTarget *aTarget)
426 : {
427 0 : if (aFlags != 0) {
428 0 : return NS_ERROR_NOT_IMPLEMENTED;
429 : }
430 :
431 0 : if (mCallback || mCallbackTarget) {
432 0 : return NS_ERROR_UNEXPECTED;
433 : }
434 :
435 0 : mCallbackTarget = aTarget;
436 : // 0 means "any number of bytes except 0"
437 0 : mNotifyThreshold = aRequestedCount;
438 0 : if (!aRequestedCount) {
439 0 : mNotifyThreshold = 1024; // We don't want to notify incessantly
440 : }
441 :
442 : // We set the callback absolutely last, because NotifyListener uses it to
443 : // determine if someone needs to be notified. If we don't set it last,
444 : // NotifyListener might try to fire off a notification to a null target
445 : // which will generally cause non-threadsafe objects to be used off the main thread
446 0 : mCallback = aCallback;
447 :
448 : // What we are being asked for may be present already
449 0 : NotifyListener();
450 0 : return NS_OK;
451 : }
452 :
453 0 : NS_IMETHODIMP nsICOEncoder::CloseWithStatus(nsresult aStatus)
454 : {
455 0 : return Close();
456 : }
457 :
458 : void
459 4 : nsICOEncoder::NotifyListener()
460 : {
461 4 : if (mCallback &&
462 0 : (GetCurrentImageBufferOffset() - mImageBufferReadPoint >= mNotifyThreshold ||
463 4 : mFinished)) {
464 0 : nsCOMPtr<nsIInputStreamCallback> callback;
465 0 : if (mCallbackTarget) {
466 0 : NS_NewInputStreamReadyEvent(getter_AddRefs(callback),
467 : mCallback,
468 0 : mCallbackTarget);
469 : } else {
470 0 : callback = mCallback;
471 : }
472 :
473 0 : NS_ASSERTION(callback, "Shouldn't fail to make the callback");
474 : // Null the callback first because OnInputStreamReady could reenter
475 : // AsyncWait
476 0 : mCallback = nsnull;
477 0 : mCallbackTarget = nsnull;
478 0 : mNotifyThreshold = 0;
479 :
480 0 : callback->OnInputStreamReady(this);
481 : }
482 4 : }
483 :
484 : // Initializes the icon file header mICOFileHeader
485 : void
486 4 : nsICOEncoder::InitFileHeader()
487 : {
488 4 : memset(&mICOFileHeader, 0, sizeof(mICOFileHeader));
489 4 : mICOFileHeader.mReserved = 0;
490 4 : mICOFileHeader.mType = 1;
491 4 : mICOFileHeader.mCount = 1;
492 4 : }
493 :
494 : // Initializes the icon directory info header mICODirEntry
495 : void
496 4 : nsICOEncoder::InitInfoHeader(PRUint32 aBPP, PRUint8 aWidth, PRUint8 aHeight)
497 : {
498 4 : memset(&mICODirEntry, 0, sizeof(mICODirEntry));
499 4 : mICODirEntry.mBitCount = aBPP;
500 4 : mICODirEntry.mBytesInRes = 0;
501 4 : mICODirEntry.mColorCount = 0;
502 4 : mICODirEntry.mWidth = aWidth;
503 4 : mICODirEntry.mHeight = aHeight;
504 4 : mICODirEntry.mImageOffset = ICONFILEHEADERSIZE + ICODIRENTRYSIZE;
505 4 : mICODirEntry.mPlanes = 1;
506 4 : mICODirEntry.mReserved = 0;
507 4 : }
508 :
509 : // Encodes the icon file header mICOFileHeader
510 : void
511 4 : nsICOEncoder::EncodeFileHeader()
512 : {
513 4 : IconFileHeader littleEndianIFH = mICOFileHeader;
514 4 : littleEndianIFH.mReserved = NATIVE16_TO_LITTLE(littleEndianIFH.mReserved);
515 4 : littleEndianIFH.mType = NATIVE16_TO_LITTLE(littleEndianIFH.mType);
516 4 : littleEndianIFH.mCount = NATIVE16_TO_LITTLE(littleEndianIFH.mCount);
517 :
518 : memcpy(mImageBufferCurr, &littleEndianIFH.mReserved,
519 4 : sizeof(littleEndianIFH.mReserved));
520 4 : mImageBufferCurr += sizeof(littleEndianIFH.mReserved);
521 : memcpy(mImageBufferCurr, &littleEndianIFH.mType,
522 4 : sizeof(littleEndianIFH.mType));
523 4 : mImageBufferCurr += sizeof(littleEndianIFH.mType);
524 : memcpy(mImageBufferCurr, &littleEndianIFH.mCount,
525 4 : sizeof(littleEndianIFH.mCount));
526 4 : mImageBufferCurr += sizeof(littleEndianIFH.mCount);
527 4 : }
528 :
529 : // Encodes the icon directory info header mICODirEntry
530 : void
531 4 : nsICOEncoder::EncodeInfoHeader()
532 : {
533 4 : IconDirEntry littleEndianmIDE = mICODirEntry;
534 :
535 4 : littleEndianmIDE.mPlanes = NATIVE16_TO_LITTLE(littleEndianmIDE.mPlanes);
536 4 : littleEndianmIDE.mBitCount = NATIVE16_TO_LITTLE(littleEndianmIDE.mBitCount);
537 : littleEndianmIDE.mBytesInRes =
538 4 : NATIVE32_TO_LITTLE(littleEndianmIDE.mBytesInRes);
539 : littleEndianmIDE.mImageOffset =
540 4 : NATIVE32_TO_LITTLE(littleEndianmIDE.mImageOffset);
541 :
542 : memcpy(mImageBufferCurr, &littleEndianmIDE.mWidth,
543 4 : sizeof(littleEndianmIDE.mWidth));
544 4 : mImageBufferCurr += sizeof(littleEndianmIDE.mWidth);
545 : memcpy(mImageBufferCurr, &littleEndianmIDE.mHeight,
546 4 : sizeof(littleEndianmIDE.mHeight));
547 4 : mImageBufferCurr += sizeof(littleEndianmIDE.mHeight);
548 : memcpy(mImageBufferCurr, &littleEndianmIDE.mColorCount,
549 4 : sizeof(littleEndianmIDE.mColorCount));
550 4 : mImageBufferCurr += sizeof(littleEndianmIDE.mColorCount);
551 : memcpy(mImageBufferCurr, &littleEndianmIDE.mReserved,
552 4 : sizeof(littleEndianmIDE.mReserved));
553 4 : mImageBufferCurr += sizeof(littleEndianmIDE.mReserved);
554 : memcpy(mImageBufferCurr, &littleEndianmIDE.mPlanes,
555 4 : sizeof(littleEndianmIDE.mPlanes));
556 4 : mImageBufferCurr += sizeof(littleEndianmIDE.mPlanes);
557 : memcpy(mImageBufferCurr, &littleEndianmIDE.mBitCount,
558 4 : sizeof(littleEndianmIDE.mBitCount));
559 4 : mImageBufferCurr += sizeof(littleEndianmIDE.mBitCount);
560 : memcpy(mImageBufferCurr, &littleEndianmIDE.mBytesInRes,
561 4 : sizeof(littleEndianmIDE.mBytesInRes));
562 4 : mImageBufferCurr += sizeof(littleEndianmIDE.mBytesInRes);
563 : memcpy(mImageBufferCurr, &littleEndianmIDE.mImageOffset,
564 4 : sizeof(littleEndianmIDE.mImageOffset));
565 4 : mImageBufferCurr += sizeof(littleEndianmIDE.mImageOffset);
566 4 : }
|