summaryrefslogtreecommitdiff
path: root/spuencoder.c
diff options
context:
space:
mode:
authorChristian Gmeiner <christian.gmeiner@gmail.com>2009-09-29 17:22:50 +0200
committerChristian Gmeiner <christian.gmeiner@gmail.com>2009-09-29 17:22:50 +0200
commita73ccf0fbd5ee4352c96dafc731f0352c7d02101 (patch)
tree56b9abee3eba994aba1dcff7eb2aedd2dab5bf53 /spuencoder.c
parentd20955f24a60b4a94532e6260188428e38472600 (diff)
downloadvdr-plugin-dxr3-a73ccf0fbd5ee4352c96dafc731f0352c7d02101.tar.gz
vdr-plugin-dxr3-a73ccf0fbd5ee4352c96dafc731f0352c7d02101.tar.bz2
add the magic calculateRegions algorithm
Diffstat (limited to 'spuencoder.c')
-rw-r--r--spuencoder.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/spuencoder.c b/spuencoder.c
index 372207f..778d75f 100644
--- a/spuencoder.c
+++ b/spuencoder.c
@@ -342,6 +342,127 @@ void cSpuEncoder::clearRegions()
void cSpuEncoder::calculateRegions()
{
+ // create temporay bitmap
+ data = new cBitmap(bitmap->Width(), bitmap->Height(), bitmap->Bpp(), bitmap->X0(), bitmap->Y0());
+
+ // we go through the whole bitmap and define
+ // spuregions and do remapping.
+
+ for (uint16_t y = 0; y < bitmap->Height(); /* y gets incremented in algorithgm */) {
+
+ cSpuRegion *reg = new cSpuRegion(y);
+ regions.push_back(reg);
+
+ tIndex prevIndex = 0xff;
+
+ // in this part of the algorithm, we go through one
+ // line of the osd and define sections for the current
+ // region.
+
+ for (uint16_t x = 0; x < bitmap->Width(); x++) {
+
+ // get current color
+ tIndex index = *(bitmap->Data(x, y));
+
+ if (prevIndex != index) {
+
+ // try to add it to current section
+ if (!reg->addIndex(index)) {
+
+ // its time to create a new section
+ // but before we continoue bring old
+ // section into a well defined state
+ reg->section(reg->openSections() - 1)->endColumn = x;
+
+ dsyslog("new sectoin %d %d", y, x);
+ // add a new section
+ if (!reg->newSection()) {
+ // TODO: what now?
+ dsyslog("out of sections");
+ }
+
+ // set some start values for new section
+ reg->section(reg->openSections() - 1)->startColumn = x;
+ reg->addIndex(index);
+ }
+
+ prevIndex = index;
+ }
+ }
+
+ // go for sure that we have set an endColumn value. this might happen
+ // if only one section was needed.
+ reg->section(reg->openSections() - 1)->endColumn = bitmap->Width();
+
+ // next we need to find the optimal endLine for the current
+ // region. this is done by growing each section and then use
+ // the minimal value for the endLine
+
+ uint16_t endLine = 0;
+ bool doneLoop = false;
+
+ for (uint8_t i = 0; i < reg->openSections(); i++) {
+ sSection *sec = reg->section(i);
+ //dsyslog("section %d", i);
+
+ for (uint16_t y = reg->startLine; !doneLoop && y < bitmap->Height(); y++) {
+ for (uint16_t x = sec->startColumn; !doneLoop && x < sec->endColumn; x++) {
+
+ tIndex idx = *(bitmap->Data(x, y));
+
+ if (!reg->containsIndex(idx)) {
+
+ if (endLine == 0) {
+ endLine = y;
+ } else {
+ endLine = std::min(endLine, y);
+ }
+
+ doneLoop = true;
+ dsyslog("loop done - color %d not found", idx);
+ }
+ }
+ }
+
+ if (endLine == reg->startLine) {
+ endLine++;
+ }
+
+ // we reached the end of the bitmap
+ if (!doneLoop) {
+ endLine = bitmap->Height();
+ }
+ }
+
+ dsyslog("endLine %d", endLine);
+ reg->endLine = endLine;
+
+ // in the last step we need to map old index values
+ // to new one. this is needed as the index value in the
+ // bitmap can only be 2 bits big (see rle method).
+
+ //dsyslog("opensections %d", reg->openSections());
+ for (uint8_t i = 0; i < reg->openSections(); i++) {
+ sSection *sec = reg->section(i);
+
+ for (uint16_t y = reg->startLine; y < reg->endLine; y++) {
+ for (uint16_t x = sec->startColumn; x < sec->endColumn; x++) {
+ tIndex idx = *(bitmap->Data(x, y));
+ data->SetIndex(x, y, sec->cmap[idx]);
+ }
+ }
+
+ // we reached the end of the bitmap
+ if (!doneLoop) {
+ endLine = bitmap->Height();
+ }
+ }
+
+ // update y
+ y = endLine;
+ }
+
+ bitmap = data;
}
void cSpuEncoder::rle4colors()