⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 picture.cc

📁 Linux下比较早的基于命令行的DVD播放器
💻 CC
字号:
//// Copyright (c) 2003 by Istv醤 V醨adi//// This file is part of dxr3Player, a DVD player written specifically // for the DXR3 (aka Hollywood+) decoder card.// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA//------------------------------------------------------------------------------#include "Picture.h"#include "SPUBuffer.h"#include <algorithm>#include <cassert>//------------------------------------------------------------------------------using dvd::spu::Picture;using std::min;using std::max;//------------------------------------------------------------------------------Picture::Picture() :     referenceCount(0), data(0), topFieldLength(0), bottomFieldLength(0){}//------------------------------------------------------------------------------Picture::~Picture(){    delete[] data;}//------------------------------------------------------------------------------Picture& Picture::operator=(const Picture& other){    invalidateCompressed();    delete[] data; data = 0;    setArea(other.area);    memcpy(data, other.data, getWidth()*getHeight());    return *this;}//------------------------------------------------------------------------------void Picture::setArea(const Area& a){    assert(data==0);    invalidateCompressed();    area = a;    visibleStartX = area.getEndX();    visibleStartY = area.getEndY();    visibleEndX = 0;    visibleEndY = 0;    size_t size = area.getWidth() * area.getHeight();    data = new unsigned char[size];    for(size_t i = 0; i < size; ++i) {        data[i] = 0;    }}//------------------------------------------------------------------------------void Picture::setArea(size_t startX, size_t endX,                       size_t startY, size_t endY){    setArea(Area(startX, endX, startY, endY));}//------------------------------------------------------------------------------void Picture::setArea(SPUBufferBitReader& reader){    size_t startX = reader.readBits(12);    size_t endX   = reader.readBits(12);    size_t startY = reader.readBits(12);    size_t endY   = reader.readBits(12);        setArea(startX, endX, startY, endY);}//------------------------------------------------------------------------------size_t Picture::encode(DynamicBufferBitWriter& writer, size_t& tfl) const{    if (!isValid()) {        tfl = 0;        return 0;    } else {        return compress(writer, tfl);    }}//------------------------------------------------------------------------------unsigned Picture::decodeVLC(SPUBufferBitReader& reader) const{    unsigned vlc = reader.readBits(4);    if (vlc<0x0004) {        vlc = (vlc<<4) | reader.readBits(4);        if (vlc<0x0010) {            vlc = (vlc<<4) | reader.readBits(4);            if (vlc<0x0040) {                vlc = (vlc<<4) | reader.readBits(4);            }        }    }        return vlc;}//------------------------------------------------------------------------------void Picture::decodeField(SPUBufferBitReader& reader, size_t line,                           unsigned contrast){    invalidateCompressed();    size_t width  = getWidth();    size_t height = getHeight();    unsigned char* dataLine = data + line * width;    while(line<height) {        size_t column = 0;        unsigned char* pixel = dataLine;        while(column<width) {            unsigned vlc = decodeVLC(reader);                        unsigned len = vlc>>2;            if (len==0) len = width-column;            unsigned color = vlc&0x03;                        if (column<visibleStartX || (column+len)>(visibleEndX+1) ||                line<visibleStartY || line>visibleEndY)            {                unsigned colorContrast = ((contrast)>>(4*color))&0x0f;                if (colorContrast>0) {                    visibleStartX = min(column, visibleStartX);                    visibleEndX = max(column+len-1, visibleEndX);                    visibleStartY = min(line, visibleStartY);                    visibleEndY = max(line, visibleStartX);                }            }            memset(pixel, color, len);            pixel += len;            column += len;        }        reader.discardCurrentByte();        line+=2;        dataLine += width*2;    }}//------------------------------------------------------------------------------void Picture::invalidateCompressed(){    compressedData.reset();    topFieldLength = bottomFieldLength = 0;}//------------------------------------------------------------------------------void Picture::compress(){    if (topFieldLength>0 || bottomFieldLength>0) return;    DynamicBufferBitWriter writer;    writer.setBuffer(compressedData);        compressField(writer, 0);    topFieldLength = writer.getOffset();    compressField(writer, 1);    bottomFieldLength = writer.getOffset() - topFieldLength;}//------------------------------------------------------------------------------size_t Picture::compress(DynamicBufferBitWriter& writer, size_t& tfl) const{    size_t offset0 = writer.getOffset();        compressField(writer, 0);    tfl = writer.getOffset() - offset0;    compressField(writer, 1);    return writer.getOffset() - offset0;}//------------------------------------------------------------------------------void Picture::compressField(DynamicBufferBitWriter& writer,                             size_t line) const{    size_t height = getHeight();    while(line<height) {        compressLine(writer, line);        line+=2;    }}//------------------------------------------------------------------------------void Picture::compressLine(DynamicBufferBitWriter& writer,                            size_t line) const{    size_t width = getWidth();        unsigned previousColor = 0;    size_t   previousLength = 0;        for(size_t x = 0; x<width; ++x) {        unsigned color = getColor(x, line);                if (color!=previousColor) {            addVLC(writer, previousColor, previousLength);            previousColor = color;            previousLength = 1;        } else ++previousLength;    }    if (previousLength>63) {        addVLCLineEnd(writer, previousColor);    } else {        addVLC(writer, previousColor, previousLength);    }    writer.finishCurrentByte();}//------------------------------------------------------------------------------void Picture::addVLC(DynamicBufferBitWriter& writer,                      unsigned color, size_t length) const{    while(length>0) {        size_t  partLength = length;        if (partLength>255) partLength = 255;        if (partLength<=3) {            writer.writeBits(partLength, 2);        } else if (partLength<=15) {            writer.writeBits(0, 2);            writer.writeBits(partLength, 4);        } else if (partLength<=63) {            writer.writeBits(0, 4);            writer.writeBits(partLength, 6);        } else {            writer.writeBits(0, 6);            writer.writeBits(partLength, 8);        }        writer.writeBits(color, 2);        length -= partLength;    }}//------------------------------------------------------------------------------void Picture::addVLCLineEnd(DynamicBufferBitWriter& writer, unsigned color) const{    writer.writeBits(0, 14);    writer.writeBits(color, 2);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -