1 /* Copyright (C) 2000-2003 Constantin Kaplinsky.  All Rights Reserved.
2  * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
3  * Copyright 2014 Pierre Ossman for Cendio AB
4  *
5  * This is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This software is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this software; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
18  * USA.
19  */
20 
21 #define CONCAT2(a,b) a##b
22 #define CONCAT2E(a,b) CONCAT2(a,b)
23 
24 #define UBPP CONCAT2E(U,BPP)
25 
checkSolidTile(const Rect & r,rdr::UBPP colourValue,const PixelBuffer * pb)26 inline bool EncodeManager::checkSolidTile(const Rect& r,
27                                           rdr::UBPP colourValue,
28                                           const PixelBuffer *pb)
29 {
30   int w, h;
31   const rdr::UBPP* buffer;
32   int stride, pad;
33 
34   w = r.width();
35   h = r.height();
36 
37   buffer = (const rdr::UBPP*)pb->getBuffer(r, &stride);
38   pad = stride - w;
39 
40   while (h--) {
41     int w_ = w;
42     while (w_--) {
43       if (*buffer != colourValue)
44         return false;
45       buffer++;
46     }
47     buffer += pad;
48   }
49 
50   return true;
51 }
52 
analyseRect(int width,int height,const rdr::UBPP * buffer,int stride,struct RectInfo * info,int maxColours)53 inline bool EncodeManager::analyseRect(int width, int height,
54                                        const rdr::UBPP* buffer, int stride,
55                                        struct RectInfo *info, int maxColours)
56 {
57   int pad;
58 
59   rdr::UBPP colour;
60   int count;
61 
62   info->rleRuns = 0;
63   info->palette.clear();
64 
65   pad = stride - width;
66 
67   // For efficiency, we only update the palette on changes in colour
68   colour = buffer[0];
69   count = 0;
70   while (height--) {
71     int w_ = width;
72     while (w_--) {
73       if (*buffer != colour) {
74         if (!info->palette.insert(colour, count))
75           return false;
76         if (info->palette.size() > maxColours)
77           return false;
78 
79         // FIXME: This doesn't account for switching lines
80         info->rleRuns++;
81 
82         colour = *buffer;
83         count = 0;
84       }
85       buffer++;
86       count++;
87     }
88     buffer += pad;
89   }
90 
91   // Make sure the final pixels also get counted
92   if (!info->palette.insert(colour, count))
93     return false;
94   if (info->palette.size() > maxColours)
95     return false;
96 
97   return true;
98 }
99