1/*
2 * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#include "utility/rect.h"
27
28#if defined(__cplusplus)
29extern "C" {
30#endif
31
32/**
33 * bitsPerPixel must be 32 for now.
34 * outBuf must be large enough to conatin all the rectangles.
35 */
36int BitmapToYXBandedRectangles(int bitsPerPixel, int width, int height, unsigned char * buf, RECT_T * outBuf)
37{
38 //XXX: we might want to reuse the code in the splashscreen library,
39 // though we'd have to deal with the ALPHA_THRESHOLD and different
40 // image formats in this case.
41 int widthBytes = width * bitsPerPixel / 8;
42 int alignedWidth = (((widthBytes - 1) / 4) + 1) * 4;
43
44 RECT_T * out = outBuf;
45
46 RECT_T *pPrevLine = NULL, *pFirst = out, *pThis = pFirst;
47 int i, j, i0;
48 int length;
49
50 for (j = 0; j < height; j++) {
51 /* generate data for a scanline */
52
53 unsigned char *pSrc = (unsigned char *) buf + j * alignedWidth;
54 RECT_T *pLine = pThis;
55
56 i = 0;
57
58 do {
59 // pSrc[0,1,2] == B,G,R; pSrc[3] == Alpha
60 while (i < width && !pSrc[3]) {
61 pSrc += 4;
62 ++i;
63 }
64 if (i >= width)
65 break;
66 i0 = i;
67 while (i < width && pSrc[3]) {
68 pSrc += 4;
69 ++i;
70 }
71 RECT_SET(*pThis, i0, j, i - i0, 1);
72 ++pThis;
73 } while (i < width);
74
75 /* check if the previous scanline is exactly the same, merge if so
76 (this is the only optimization we can use for YXBanded rectangles,
77 and win32 supports YXBanded only */
78
79 length = pThis - pLine;
80 if (pPrevLine && pLine - pPrevLine == length) {
81 for (i = 0; i < length && RECT_EQ_X(pPrevLine[i], pLine[i]); ++i) {
82 }
83 if (i == pLine - pPrevLine) {
84 // do merge
85 for (i = 0; i < length; i++) {
86 RECT_INC_HEIGHT(pPrevLine[i]);
87 }
88 pThis = pLine;
89 continue;
90 }
91 }
92 /* or else use the generated scanline */
93
94 pPrevLine = pLine;
95 }
96
97 return pThis - pFirst;
98}
99
100#if defined(__cplusplus)
101}
102#endif
103