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) 29 extern "C" { 30 #endif 31 32 /** 33 * bitsPerPixel must be 32 for now. 34 * outBuf must be large enough to conatin all the rectangles. 35 */ 36 int 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 = (int)(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 (int)(pThis - pFirst); 98 } 99 100 #if defined(__cplusplus) 101 } 102 #endif