Ogg support fixed and re-added. Squash of various commits made by Wouter Spruit.
This commit is contained in:
parent
689e1d714e
commit
4d9f4da3f1
11 changed files with 1238 additions and 465 deletions
324
lib/theora.cpp
324
lib/theora.cpp
|
@ -3,12 +3,13 @@
|
|||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sstream>
|
||||
#include "defines.h"
|
||||
|
||||
namespace theora {
|
||||
bool header::checkDataSize(unsigned int size) {
|
||||
if (size > datasize) {
|
||||
bool header::checkDataSize(unsigned int size){
|
||||
if (size > datasize){
|
||||
void * tmp = realloc(data, size);
|
||||
if (tmp) {
|
||||
if (tmp){
|
||||
data = (char *)tmp;
|
||||
datasize = size;
|
||||
return true;
|
||||
|
@ -20,286 +21,241 @@ namespace theora {
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t header::getInt32(size_t index) {
|
||||
if (datasize >= (index + 3)) {
|
||||
uint32_t header::getInt32(size_t index){
|
||||
if (datasize >= (index + 3)){
|
||||
return (data[index] << 24) + (data[index + 1] << 16) + (data[index + 2] << 8) + data[index + 3];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t header::getInt24(size_t index) {
|
||||
if (datasize >= (index + 2)) {
|
||||
uint32_t header::getInt24(size_t index){
|
||||
if (datasize >= (index + 2)){
|
||||
return 0 + (data[index] << 16) + (data[index + 1] << 8) + data[index + 2];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t header::getInt16(size_t index) {
|
||||
if (datasize >= (index + 1)) {
|
||||
uint16_t header::getInt16(size_t index){
|
||||
if (datasize >= (index + 1)){
|
||||
return 0 + (data[index] << 8) + data[index + 1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t header::commentLen(size_t index) {
|
||||
if (datasize >= index + 3) {
|
||||
uint32_t header::commentLen(size_t index){
|
||||
if (datasize >= index + 3){
|
||||
return data[index] + (data[index + 1] << 8) + (data[index + 2] << 16) + (data[index + 3] << 24);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
header::header() {
|
||||
data = NULL;
|
||||
datasize = 0;
|
||||
header::header(char * newData, unsigned int length){
|
||||
data = newData;
|
||||
datasize = length;
|
||||
}
|
||||
|
||||
header::header(char * newData, unsigned int length) {
|
||||
data = NULL;
|
||||
datasize = 0;
|
||||
read(newData, length);
|
||||
header::~header(){
|
||||
}
|
||||
|
||||
bool header::validateIdentificationHeader() {
|
||||
if (datasize != 42) {
|
||||
bool isHeader(const char * newData, unsigned int length){
|
||||
if (length < 7){
|
||||
return false;
|
||||
}
|
||||
if (getHeaderType() != 0) {
|
||||
if (! newData[0] & 0x80){
|
||||
DEBUG_MSG(DLVL_FAIL, "newdata != 0x80: %0.2X", newData[0]);
|
||||
return false;
|
||||
}
|
||||
if (getVMAJ() != 3) {
|
||||
return false;
|
||||
}
|
||||
if (getVMIN() != 2) {
|
||||
return false;
|
||||
}
|
||||
if (getFMBW() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (getFMBH() == 0) {
|
||||
return false;
|
||||
}
|
||||
if ((short)getPICW() > getFMBW() * 16) {
|
||||
return false;
|
||||
}
|
||||
if ((short)getPICH() > getFMBH() * 16) {
|
||||
return false;
|
||||
}
|
||||
if ((short)getPICX() > (getFMBW() * 16) - (short)getPICW()) {
|
||||
return false;
|
||||
}
|
||||
if ((short)getPICY() > (getFMBH() * 16) - (short)getPICH()) {
|
||||
return false;
|
||||
}
|
||||
if (getFRN() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (getFRD() == 0) {
|
||||
if (memcmp(newData + 1, "theora", 6) != 0){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool header::read(char * newData, unsigned int length) {
|
||||
if (length < 7) {
|
||||
return false;
|
||||
}
|
||||
if (!(newData[0] & 0x80)) {
|
||||
return false;
|
||||
}
|
||||
if (memcmp(newData + 1, "theora", 6) != 0) {
|
||||
return false;
|
||||
}
|
||||
if (checkDataSize(length)) {
|
||||
memcpy(data, newData, length);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
switch (getHeaderType()) {
|
||||
case 0:
|
||||
return validateIdentificationHeader();
|
||||
break;
|
||||
case 1:
|
||||
///\todo Read Comment header
|
||||
break;
|
||||
case 2:
|
||||
///\todo Read Setup Header
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int header::getHeaderType() {
|
||||
int header::getHeaderType(){
|
||||
return (data[0] & 0x7F);
|
||||
}
|
||||
|
||||
char header::getVMAJ() {
|
||||
if (getHeaderType() == 0) {
|
||||
char header::getVMAJ(){
|
||||
if (getHeaderType() == 0){
|
||||
return data[7];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getVMIN() {
|
||||
if (getHeaderType() == 0) {
|
||||
char header::getVMIN(){
|
||||
if (getHeaderType() == 0){
|
||||
return data[8];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getVREV() {
|
||||
if (getHeaderType() == 0) {
|
||||
char header::getVREV(){
|
||||
if (getHeaderType() == 0){
|
||||
return data[9];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
short header::getFMBW() {
|
||||
if (getHeaderType() == 0) {
|
||||
short header::getFMBW(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt16(10);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
short header::getFMBH() {
|
||||
if (getHeaderType() == 0) {
|
||||
short header::getFMBH(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt16(12);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getPICX() {
|
||||
if (getHeaderType() == 0) {
|
||||
char header::getPICX(){
|
||||
if (getHeaderType() == 0){
|
||||
return data[20];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getPICY() {
|
||||
if (getHeaderType() == 0) {
|
||||
char header::getPICY(){
|
||||
if (getHeaderType() == 0){
|
||||
return data[21];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getKFGShift() {
|
||||
if (getHeaderType() == 0) {
|
||||
char header::getKFGShift(){
|
||||
if (getHeaderType() == 0){
|
||||
return (getInt16(40) >> 5) & 0x1F;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long unsigned int header::getFRN() {
|
||||
if (getHeaderType() == 0) {
|
||||
long unsigned int header::getFRN(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt32(22);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long unsigned int header::getPICH() {
|
||||
if (getHeaderType() == 0) {
|
||||
long unsigned int header::getPICH(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt24(17);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long unsigned int header::getPICW() {
|
||||
if (getHeaderType() == 0) {
|
||||
long unsigned int header::getPICW(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt24(14);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long unsigned int header::getFRD() {
|
||||
if (getHeaderType() == 0) {
|
||||
long unsigned int header::getFRD(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt32(26);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long unsigned int header::getPARN() {
|
||||
if (getHeaderType() == 0) {
|
||||
long unsigned int header::getPARN(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt24(30);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long unsigned int header::getPARD() {
|
||||
if (getHeaderType() == 0) {
|
||||
long unsigned int header::getPARD(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt24(33);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getCS() {
|
||||
if (getHeaderType() == 0) {
|
||||
char header::getCS(){
|
||||
if (getHeaderType() == 0){
|
||||
return data[36];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long unsigned int header::getNOMBR() {
|
||||
if (getHeaderType() == 0) {
|
||||
long unsigned int header::getNOMBR(){
|
||||
if (getHeaderType() == 0){
|
||||
return getInt24(37);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getQUAL() {
|
||||
if (getHeaderType() == 0) {
|
||||
char header::getQUAL(){
|
||||
if (getHeaderType() == 0){
|
||||
return (data[40] >> 3) & 0x1F;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char header::getPF() {
|
||||
if (getHeaderType() == 0) {
|
||||
char header::getPF(){
|
||||
if (getHeaderType() == 0){
|
||||
return (data[41] >> 3) & 0x03;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string header::getVendor() {
|
||||
if (getHeaderType() != 1) {
|
||||
std::string header::getVendor(){
|
||||
if (getHeaderType() != 1){
|
||||
return "";
|
||||
}
|
||||
return std::string(data + 11, commentLen(7));
|
||||
}
|
||||
|
||||
long unsigned int header::getNComments() {
|
||||
if (getHeaderType() != 1) {
|
||||
long unsigned int header::getNComments(){
|
||||
if (getHeaderType() != 1){
|
||||
return 0;
|
||||
}
|
||||
int offset = 11 + commentLen(7);
|
||||
return commentLen(offset);
|
||||
}
|
||||
|
||||
char header::getLFLIMS(size_t index) {
|
||||
if (getHeaderType() != 2) {
|
||||
char header::getLFLIMS(size_t index){
|
||||
if (getHeaderType() != 2){
|
||||
return 0;
|
||||
}
|
||||
if (index >= 64) {
|
||||
if (index >= 64){
|
||||
return 0;
|
||||
}
|
||||
char NBITS = (data[0] >> 5) & 0x07;
|
||||
return NBITS;
|
||||
}
|
||||
|
||||
std::string header::getUserComment(size_t index) {
|
||||
if (index >= getNComments()) {
|
||||
std::string header::getUserComment(size_t index){
|
||||
if (index >= getNComments()){
|
||||
return "";
|
||||
}
|
||||
int offset = 11 + commentLen(7) + 4;
|
||||
for (size_t i = 0; i < index; i++) {
|
||||
for (size_t i = 0; i < index; i++){
|
||||
offset += 4 + commentLen(offset);
|
||||
}
|
||||
return std::string(data + offset + 4, commentLen(offset));
|
||||
}
|
||||
|
||||
std::string header::toPrettyString(size_t indent) {
|
||||
char header::getFTYPE(){
|
||||
return (data[0] >> 6) & 0x01;
|
||||
}
|
||||
|
||||
bool header::isHeader(){
|
||||
return ::theora::isHeader(data, datasize);
|
||||
}
|
||||
|
||||
std::string header::toPrettyString(size_t indent){
|
||||
std::stringstream result;
|
||||
if(!isHeader()){
|
||||
result << std::string(indent, ' ') << "Theora Frame" << std::endl;
|
||||
result << std::string(indent + 2, ' ') << "FType: " << (int)getFTYPE() << std::endl;
|
||||
return result.str();
|
||||
}
|
||||
result << std::string(indent, ' ') << "Theora header" << std::endl;
|
||||
result << std::string(indent + 2, ' ') << "HeaderType: " << getHeaderType() << std::endl;
|
||||
switch (getHeaderType()) {
|
||||
switch (getHeaderType()){
|
||||
case 0:
|
||||
result << std::string(indent + 2, ' ') << "VMAJ: " << (int)getVMAJ() << std::endl;
|
||||
result << std::string(indent + 2, ' ') << "VMIN: " << (int)getVMIN() << std::endl;
|
||||
|
@ -322,7 +278,7 @@ namespace theora {
|
|||
case 1:
|
||||
result << std::string(indent + 2, ' ') << "Vendor: " << getVendor() << std::endl;
|
||||
result << std::string(indent + 2, ' ') << "User Comments (" << getNComments() << "):" << std::endl;
|
||||
for (long unsigned int i = 0; i < getNComments(); i++) {
|
||||
for (long unsigned int i = 0; i < getNComments(); i++){
|
||||
result << std::string(indent + 4, ' ') << "[" << i << "] " << getUserComment(i) << std::endl;
|
||||
}
|
||||
break;
|
||||
|
@ -331,69 +287,79 @@ namespace theora {
|
|||
}
|
||||
return result.str();
|
||||
}
|
||||
/*
|
||||
frame::frame(){
|
||||
data = NULL;
|
||||
datasize = 0;
|
||||
}
|
||||
|
||||
frame::frame() {
|
||||
data = NULL;
|
||||
datasize = 0;
|
||||
}
|
||||
frame::~frame(){
|
||||
if (data){
|
||||
free(data);
|
||||
}
|
||||
data = 0;
|
||||
}
|
||||
|
||||
bool frame::checkDataSize(unsigned int size) {
|
||||
if (size > datasize) {
|
||||
void * tmp = realloc(data, size);
|
||||
if (tmp) {
|
||||
data = (char *)tmp;
|
||||
datasize = size;
|
||||
bool frame::checkDataSize(unsigned int size){
|
||||
if (size > datasize){
|
||||
void * tmp = realloc(data, size);
|
||||
if (tmp){
|
||||
data = (char *)tmp;
|
||||
datasize = size;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool frame::read(const char * newData, unsigned int length){
|
||||
if (length < 7){
|
||||
return false;
|
||||
}
|
||||
if ((newData[0] & 0x80)){
|
||||
return false;
|
||||
}
|
||||
if (checkDataSize(length)){
|
||||
memcpy(data, newData, length);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool frame::read(char * newData, unsigned int length) {
|
||||
if (length < 7) {
|
||||
return false;
|
||||
}
|
||||
if ((newData[0] & 0x80)) {
|
||||
return false;
|
||||
}
|
||||
if (checkDataSize(length)) {
|
||||
memcpy(data, newData, length);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
char frame::getFTYPE() {
|
||||
return (data[0] >> 6) & 0x01;
|
||||
}
|
||||
|
||||
char frame::getNQIS() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char frame::getQIS(size_t index) {
|
||||
if (index >= 3) {
|
||||
char frame::getNQIS(){
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long long unsigned int header::parseGranuleUpper(long long unsigned int granPos) {
|
||||
return granPos >> getKFGShift();
|
||||
}
|
||||
char frame::getQIS(size_t index){
|
||||
if (index >= 3){
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
long long unsigned int header::parseGranuleUpper(long long unsigned int granPos){
|
||||
return granPos >> getKFGShift();
|
||||
}
|
||||
|
||||
long long unsigned int header::parseGranuleLower(long long unsigned int granPos) {
|
||||
return (granPos & ((1 << getKFGShift()) - 1));
|
||||
}
|
||||
|
||||
std::string frame::toPrettyString(size_t indent) {
|
||||
std::stringstream result;
|
||||
result << std::string(indent, ' ') << "Theora Frame" << std::endl;
|
||||
result << std::string(indent + 2, ' ') << "FType: " << (int)getFTYPE() << std::endl;
|
||||
return result.str();
|
||||
}
|
||||
long long unsigned int header::parseGranuleLower(long long unsigned int granPos){
|
||||
return (granPos & ((1 << getKFGShift()) - 1));
|
||||
}*/
|
||||
/*
|
||||
std::string frame::toPrettyString(size_t indent){
|
||||
std::stringstream result;
|
||||
result << std::string(indent, ' ') << "Theora Frame" << std::endl;
|
||||
result << std::string(indent + 2, ' ') << "FType: " << (int)getFTYPE() << std::endl;
|
||||
return result.str();
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue