112fd6cc2SKarsten Heimrich /*
212fd6cc2SKarsten Heimrich * ValidRect.cpp
312fd6cc2SKarsten Heimrich * Copyright 1999-2000 Y.Takagi. All Rights Reserved.
412fd6cc2SKarsten Heimrich * Copyright 2005 Michael Pfeiffer. All Rights Reserved.
512fd6cc2SKarsten Heimrich * - Rewrote get_valid_rect from scratch.
612fd6cc2SKarsten Heimrich */
712fd6cc2SKarsten Heimrich
812fd6cc2SKarsten Heimrich #include <Bitmap.h>
912fd6cc2SKarsten Heimrich #include "ValidRect.h"
1012fd6cc2SKarsten Heimrich
1112fd6cc2SKarsten Heimrich #define INLINE inline
1212fd6cc2SKarsten Heimrich
1312fd6cc2SKarsten Heimrich class BoundsCalculator
1412fd6cc2SKarsten Heimrich {
1512fd6cc2SKarsten Heimrich public:
1612fd6cc2SKarsten Heimrich bool getValidRect(BBitmap *bitmap, RECT *rect);
1712fd6cc2SKarsten Heimrich
1812fd6cc2SKarsten Heimrich private:
1912fd6cc2SKarsten Heimrich const uchar *fBits;
2012fd6cc2SKarsten Heimrich int fBPR;
2112fd6cc2SKarsten Heimrich int fLeft;
2212fd6cc2SKarsten Heimrich int fRight;
2312fd6cc2SKarsten Heimrich int fTop;
2412fd6cc2SKarsten Heimrich int fBottom;
2512fd6cc2SKarsten Heimrich int fWidth;
2612fd6cc2SKarsten Heimrich
2712fd6cc2SKarsten Heimrich int fLeftBound;
2812fd6cc2SKarsten Heimrich int fRightBound;
2912fd6cc2SKarsten Heimrich
3012fd6cc2SKarsten Heimrich INLINE bool isEmpty(const rgb_color *pixel);
3112fd6cc2SKarsten Heimrich
3212fd6cc2SKarsten Heimrich INLINE bool isRowEmpty(const rgb_color *row);
3312fd6cc2SKarsten Heimrich
3412fd6cc2SKarsten Heimrich INLINE const uchar *getRow(int x, int y);
3512fd6cc2SKarsten Heimrich
3612fd6cc2SKarsten Heimrich int getTop();
3712fd6cc2SKarsten Heimrich
3812fd6cc2SKarsten Heimrich int getBottom();
3912fd6cc2SKarsten Heimrich
4012fd6cc2SKarsten Heimrich INLINE void updateLeftBound(const rgb_color *row);
4112fd6cc2SKarsten Heimrich INLINE void updateRightBound(const rgb_color *row);
4212fd6cc2SKarsten Heimrich };
4312fd6cc2SKarsten Heimrich
44*08d759feSMichael Pfeiffer
4512fd6cc2SKarsten Heimrich bool
isEmpty(const rgb_color * pixel)4612fd6cc2SKarsten Heimrich BoundsCalculator::isEmpty(const rgb_color *pixel)
4712fd6cc2SKarsten Heimrich {
4812fd6cc2SKarsten Heimrich return pixel->red == 0xff && pixel->green == 0xff && pixel->blue == 0xff;
4912fd6cc2SKarsten Heimrich }
5012fd6cc2SKarsten Heimrich
5112fd6cc2SKarsten Heimrich
5212fd6cc2SKarsten Heimrich bool
isRowEmpty(const rgb_color * row)5312fd6cc2SKarsten Heimrich BoundsCalculator::isRowEmpty(const rgb_color *row)
5412fd6cc2SKarsten Heimrich {
5512fd6cc2SKarsten Heimrich for (int x = 0; x < fWidth; x ++) {
5612fd6cc2SKarsten Heimrich if (!isEmpty(row)) {
5712fd6cc2SKarsten Heimrich return false;
5812fd6cc2SKarsten Heimrich }
5912fd6cc2SKarsten Heimrich row ++;
6012fd6cc2SKarsten Heimrich }
6112fd6cc2SKarsten Heimrich return true;
6212fd6cc2SKarsten Heimrich }
6312fd6cc2SKarsten Heimrich
64*08d759feSMichael Pfeiffer
6512fd6cc2SKarsten Heimrich const uchar *
getRow(int x,int y)6612fd6cc2SKarsten Heimrich BoundsCalculator::getRow(int x, int y)
6712fd6cc2SKarsten Heimrich {
6812fd6cc2SKarsten Heimrich return fBits + x + fBPR * y;
6912fd6cc2SKarsten Heimrich }
7012fd6cc2SKarsten Heimrich
71*08d759feSMichael Pfeiffer
7212fd6cc2SKarsten Heimrich int
getTop()7312fd6cc2SKarsten Heimrich BoundsCalculator::getTop()
7412fd6cc2SKarsten Heimrich {
7512fd6cc2SKarsten Heimrich const uchar* row = getRow(fLeft, fTop);
7612fd6cc2SKarsten Heimrich
7712fd6cc2SKarsten Heimrich int top;
7812fd6cc2SKarsten Heimrich for (top = fTop; top <= fBottom; top ++) {
7912fd6cc2SKarsten Heimrich if (!isRowEmpty((const rgb_color*)row)) {
8012fd6cc2SKarsten Heimrich break;
8112fd6cc2SKarsten Heimrich }
8212fd6cc2SKarsten Heimrich row += fBPR;
8312fd6cc2SKarsten Heimrich }
8412fd6cc2SKarsten Heimrich
8512fd6cc2SKarsten Heimrich return top;
8612fd6cc2SKarsten Heimrich }
8712fd6cc2SKarsten Heimrich
88*08d759feSMichael Pfeiffer
8912fd6cc2SKarsten Heimrich int
getBottom()9012fd6cc2SKarsten Heimrich BoundsCalculator::getBottom()
9112fd6cc2SKarsten Heimrich {
9212fd6cc2SKarsten Heimrich const uchar *row = getRow(fLeft, fBottom);
9312fd6cc2SKarsten Heimrich
9412fd6cc2SKarsten Heimrich int bottom;
9512fd6cc2SKarsten Heimrich for (bottom = fBottom; bottom >= fTop; bottom --) {
9612fd6cc2SKarsten Heimrich if (!isRowEmpty((const rgb_color*)row)) {
9712fd6cc2SKarsten Heimrich break;
9812fd6cc2SKarsten Heimrich }
9912fd6cc2SKarsten Heimrich row -= fBPR;
10012fd6cc2SKarsten Heimrich }
10112fd6cc2SKarsten Heimrich
10212fd6cc2SKarsten Heimrich return bottom;
10312fd6cc2SKarsten Heimrich }
10412fd6cc2SKarsten Heimrich
105*08d759feSMichael Pfeiffer
10612fd6cc2SKarsten Heimrich void
updateLeftBound(const rgb_color * row)10712fd6cc2SKarsten Heimrich BoundsCalculator::updateLeftBound(const rgb_color *row)
10812fd6cc2SKarsten Heimrich {
10912fd6cc2SKarsten Heimrich for (int x = fLeft; x < fLeftBound; x ++) {
11012fd6cc2SKarsten Heimrich if (!isEmpty(row)) {
11112fd6cc2SKarsten Heimrich fLeftBound = x;
11212fd6cc2SKarsten Heimrich return;
11312fd6cc2SKarsten Heimrich }
11412fd6cc2SKarsten Heimrich row ++;
11512fd6cc2SKarsten Heimrich }
11612fd6cc2SKarsten Heimrich }
11712fd6cc2SKarsten Heimrich
118*08d759feSMichael Pfeiffer
11912fd6cc2SKarsten Heimrich void
updateRightBound(const rgb_color * row)12012fd6cc2SKarsten Heimrich BoundsCalculator::updateRightBound(const rgb_color *row)
12112fd6cc2SKarsten Heimrich {
12212fd6cc2SKarsten Heimrich row += fWidth - 1;
12312fd6cc2SKarsten Heimrich for (int x = fRight; x > fRightBound; x --) {
12412fd6cc2SKarsten Heimrich if (!isEmpty(row)) {
12512fd6cc2SKarsten Heimrich fRightBound = x;
12612fd6cc2SKarsten Heimrich return;
12712fd6cc2SKarsten Heimrich }
12812fd6cc2SKarsten Heimrich row --;
12912fd6cc2SKarsten Heimrich }
13012fd6cc2SKarsten Heimrich }
13112fd6cc2SKarsten Heimrich
132*08d759feSMichael Pfeiffer
13312fd6cc2SKarsten Heimrich // returns false if the bitmap is empty or has wrong color space.
13412fd6cc2SKarsten Heimrich bool
getValidRect(BBitmap * bitmap,RECT * rect)13512fd6cc2SKarsten Heimrich BoundsCalculator::getValidRect(BBitmap *bitmap, RECT *rect)
13612fd6cc2SKarsten Heimrich {
13712fd6cc2SKarsten Heimrich enum {
13812fd6cc2SKarsten Heimrich kRectIsInvalid = false,
13912fd6cc2SKarsten Heimrich kRectIsEmpty = false,
14012fd6cc2SKarsten Heimrich kRectIsValid = true
14112fd6cc2SKarsten Heimrich };
14212fd6cc2SKarsten Heimrich
14312fd6cc2SKarsten Heimrich switch (bitmap->ColorSpace()) {
14412fd6cc2SKarsten Heimrich case B_RGB32:
14512fd6cc2SKarsten Heimrich case B_RGB32_BIG:
14612fd6cc2SKarsten Heimrich break;
14712fd6cc2SKarsten Heimrich default:
14812fd6cc2SKarsten Heimrich return kRectIsInvalid;
14912fd6cc2SKarsten Heimrich break;
15012fd6cc2SKarsten Heimrich };
15112fd6cc2SKarsten Heimrich
15212fd6cc2SKarsten Heimrich // initialize member variables
15312fd6cc2SKarsten Heimrich fBits = (uchar*)bitmap->Bits();
15412fd6cc2SKarsten Heimrich fBPR = bitmap->BytesPerRow();
15512fd6cc2SKarsten Heimrich
15612fd6cc2SKarsten Heimrich fLeft = rect->left;
15712fd6cc2SKarsten Heimrich fRight = rect->right;
15812fd6cc2SKarsten Heimrich fTop = rect->top;
15912fd6cc2SKarsten Heimrich fBottom = rect->bottom;
16012fd6cc2SKarsten Heimrich
16112fd6cc2SKarsten Heimrich fWidth = fRight - fLeft + 1;
16212fd6cc2SKarsten Heimrich
16312fd6cc2SKarsten Heimrich // get top bound
16412fd6cc2SKarsten Heimrich fTop = getTop();
16512fd6cc2SKarsten Heimrich if (fTop > fBottom) {
16612fd6cc2SKarsten Heimrich return kRectIsEmpty;
16712fd6cc2SKarsten Heimrich }
16812fd6cc2SKarsten Heimrich
16912fd6cc2SKarsten Heimrich // get bottom bound
17012fd6cc2SKarsten Heimrich fBottom = getBottom();
17112fd6cc2SKarsten Heimrich
17212fd6cc2SKarsten Heimrich // calculate left and right bounds
17312fd6cc2SKarsten Heimrich fLeftBound = fRight + 1;
17412fd6cc2SKarsten Heimrich fRightBound = fLeft - 1;
17512fd6cc2SKarsten Heimrich
17612fd6cc2SKarsten Heimrich const uchar *row = getRow(fLeft, fTop);
17712fd6cc2SKarsten Heimrich for (int y = fTop; y <= fBottom; y ++) {
17812fd6cc2SKarsten Heimrich updateLeftBound((const rgb_color*)row);
17912fd6cc2SKarsten Heimrich updateRightBound((const rgb_color*)row);
18012fd6cc2SKarsten Heimrich if (fLeft == fLeftBound && fRight == fRightBound) {
18112fd6cc2SKarsten Heimrich break;
18212fd6cc2SKarsten Heimrich }
18312fd6cc2SKarsten Heimrich row += fBPR;
18412fd6cc2SKarsten Heimrich }
18512fd6cc2SKarsten Heimrich
18612fd6cc2SKarsten Heimrich // return bounds in rectangle
18712fd6cc2SKarsten Heimrich rect->left = fLeftBound;
18812fd6cc2SKarsten Heimrich rect->right = fRightBound;
18912fd6cc2SKarsten Heimrich rect->top = fTop;
19012fd6cc2SKarsten Heimrich rect->bottom = fBottom;
19112fd6cc2SKarsten Heimrich
19212fd6cc2SKarsten Heimrich return kRectIsValid;
19312fd6cc2SKarsten Heimrich }
19412fd6cc2SKarsten Heimrich
195*08d759feSMichael Pfeiffer
get_valid_rect(BBitmap * a_bitmap,RECT * rc)19612fd6cc2SKarsten Heimrich bool get_valid_rect(BBitmap *a_bitmap, RECT *rc)
19712fd6cc2SKarsten Heimrich {
19812fd6cc2SKarsten Heimrich BoundsCalculator calculator;
19912fd6cc2SKarsten Heimrich return calculator.getValidRect(a_bitmap, rc);
20012fd6cc2SKarsten Heimrich }
20112fd6cc2SKarsten Heimrich
202*08d759feSMichael Pfeiffer
color_space2pixel_depth(color_space cs)20312fd6cc2SKarsten Heimrich int color_space2pixel_depth(color_space cs)
20412fd6cc2SKarsten Heimrich {
20512fd6cc2SKarsten Heimrich int pixel_depth;
20612fd6cc2SKarsten Heimrich
20712fd6cc2SKarsten Heimrich switch (cs) {
20812fd6cc2SKarsten Heimrich case B_GRAY1: /* Y0[0],Y1[0],Y2[0],Y3[0],Y4[0],Y5[0],Y6[0],Y7[0] */
20912fd6cc2SKarsten Heimrich pixel_depth = 1;
21012fd6cc2SKarsten Heimrich break;
21112fd6cc2SKarsten Heimrich case B_GRAY8: /* Y[7:0] */
21212fd6cc2SKarsten Heimrich case B_CMAP8: /* D[7:0] */
21312fd6cc2SKarsten Heimrich pixel_depth = 8;
21412fd6cc2SKarsten Heimrich break;
21512fd6cc2SKarsten Heimrich case B_RGB15: /* G[2:0],B[4:0] -[0],R[4:0],G[4:3] */
21612fd6cc2SKarsten Heimrich case B_RGB15_BIG: /* -[0],R[4:0],G[4:3] G[2:0],B[4:0] */
21712fd6cc2SKarsten Heimrich pixel_depth = 16;
21812fd6cc2SKarsten Heimrich break;
21912fd6cc2SKarsten Heimrich case B_RGB32: /* B[7:0] G[7:0] R[7:0] -[7:0] */
22012fd6cc2SKarsten Heimrich case B_RGB32_BIG: /* -[7:0] R[7:0] G[7:0] B[7:0] */
22112fd6cc2SKarsten Heimrich pixel_depth = 32;
22212fd6cc2SKarsten Heimrich break;
22312fd6cc2SKarsten Heimrich default:
22412fd6cc2SKarsten Heimrich pixel_depth = 0;
22512fd6cc2SKarsten Heimrich break;
22612fd6cc2SKarsten Heimrich }
22712fd6cc2SKarsten Heimrich return pixel_depth;
22812fd6cc2SKarsten Heimrich }
229