📄 bisk3d.c
字号:
/* * * QccPack: Quantization, compression, and coding libraries * Copyright (C) 1997-2009 James E. Fowler * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * */#include "libQccPack.h"#define QCCBISK3D_BOUNDARY_VALUE 0#define QCCBISK3D_INSIGNIFICANT 0#define QCCBISK3D_SIGNIFICANT 1#define QCCBISK3D_NEWLY_SIGNIFICANT 2#define QCCBISK3D_EMPTYSET 3#define QCCBISK3D_POSITIVE 0#define QCCBISK3D_NEGATIVE 1#define QCCBISK3D_SIGNIFICANCEMASK 0x03#define QCCBISK3D_SIGNMASK 0x04#define QCCBISK3D_MAXBITPLANES 128#define QCCBISK3D_CONTEXT_NOCODE -1#define QCCBISK3D_CONTEXT_SIGNIFICANCE 0#define QCCBISK3D_CONTEXT_SIGNIFICANCE_SUBSET1 1#define QCCBISK3D_CONTEXT_SIGNIFICANCE_SUBSET2 2#define QCCBISK3D_CONTEXT_SIGN 3#define QCCBISK3D_CONTEXT_REFINEMENT 4#define QCCBISK3D_NUM_CONTEXTS 5static const int QccWAVbisk3DNumSymbols[] = { 2, 2, 2, 2, 2 };#define QCCBISK3D_HORIZONTALSPLIT 0#define QCCBISK3D_VERTICALSPLIT 1#define QCCBISK3D_SPECTRALSPLIT 2typedef struct{ char temporal_splits; char horizontal_splits; char vertical_splits; int origin_frame; int origin_row; int origin_col; int num_frames; int num_rows; int num_cols; char significance;} QccWAVbisk3DSet;static void QccWAVbisk3DPutSignificance(unsigned char *state, int significance){ *state &= (0xff ^ QCCBISK3D_SIGNIFICANCEMASK); *state |= significance;}static int QccWAVbisk3DGetSignificance(unsigned char state){ return(state & QCCBISK3D_SIGNIFICANCEMASK);}static void QccWAVbisk3DPutSign(unsigned char *state, int sign_value){ if (sign_value) *state |= QCCBISK3D_SIGNMASK; else *state &= (0xff ^ QCCBISK3D_SIGNMASK); }static int QccWAVbisk3DGetSign(unsigned char state){ return((state & QCCBISK3D_SIGNMASK) == QCCBISK3D_SIGNMASK);}static int QccWAVbisk3DTransparent(const QccWAVSubbandPyramid3D *mask, int frame, int row, int col){ if (mask == NULL) return(0); return(QccAlphaTransparent(mask->volume[frame][row][col]));}static int QccWAVbisk3DSetIsPixel(QccWAVbisk3DSet *set){ if ((set->num_frames == 1) && (set->num_rows == 1) && (set->num_cols == 1)) return(1); return(0);}#if 0static void QccWAVbisk3DSetPrint(const QccWAVbisk3DSet *set){ printf("<%c,%d,%d,%d,%d,%d,%d,%d,%d,%c>\n", ((set->type == QCCBISK3D_set) ? 'S' : 'I'), set->temporal_splits, set->horizontal_splits, set->vertical_splits, set->origin_frame, set->origin_row, set->origin_col, set->num_frames, set->num_rows, set->num_cols, ((set->significance == QCCBISK3D_INSIGNIFICANT) ? 'i' : ((set->significance == QCCBISK3D_SIGNIFICANT) ? 's' : 'S')));}static void QccWAVbisk3DLISPrint(const QccList *LIS){ QccListNode *current_list_node; QccList *current_list; QccListNode *current_set_node; QccWAVbisk3DSet *current_set; int temporal_splits, horizontal_splits, vertical_splits = 0; printf("LIS:\n"); current_list_node = LIS->start; while (current_list_node != NULL) { printf("Temporal Splits %d:\n", temporal_splits++); printf("Horizontal Splits %d:\n", horizontal_splits++); printf("Vertical Splits %d:\n", vertical_splits++); current_list = (QccList *)(current_list_node->value); current_set_node = current_list->start; while (current_set_node != NULL) { current_set = (QccWAVbisk3DSet *)(current_set_node->value); QccWAVbisk3DSetPrint(current_set); current_set_node = current_set_node->next; } current_list_node = current_list_node->next; } printf("===============================================\n"); fflush(stdout);}static void QccWAVbisk3DLSPPrint(const QccList *LSP){ QccListNode *current_set_node; QccWAVbisk3DSet *current_set; printf("LSP:\n"); current_set_node = LSP->start; while (current_set_node != NULL) { current_set = (QccWAVbisk3DSet *)(current_set_node->value); QccWAVbisk3DSetPrint(current_set); current_set_node = current_set_node->next; } printf("===============================================\n"); fflush(stdout);}#endifstatic int QccWAVbisk3DSetShrink(QccWAVbisk3DSet *set, const QccWAVSubbandPyramid3D *mask){ int row, col, frame; int min_frame = MAXINT; int min_row = MAXINT; int min_col = MAXINT; int max_frame = -MAXINT; int max_row = -MAXINT; int max_col = -MAXINT; int totally_transparent = 1; if (mask == NULL) { if ((!set->num_frames) || (!set->num_rows) || (!set->num_cols)) return(2); else return(0); } for (frame = 0; frame < set->num_frames; frame++) for (row = 0; row < set->num_rows; row++) for (col = 0; col < set->num_cols; col++) if (!QccWAVbisk3DTransparent(mask, frame + set->origin_frame, row + set->origin_row, col + set->origin_col)) { totally_transparent = 0; max_frame = QccMathMax(max_frame, frame + set->origin_frame); max_row = QccMathMax(max_row, row + set->origin_row); max_col = QccMathMax(max_col, col + set->origin_col); min_frame = QccMathMin(min_frame, frame + set->origin_frame); min_row = QccMathMin(min_row, row + set->origin_row); min_col = QccMathMin(min_col, col + set->origin_col); } if (totally_transparent) return(2); set->origin_frame = min_frame; set->origin_row = min_row; set->origin_col = min_col; set->num_frames = max_frame - min_frame + 1; set->num_rows = max_row - min_row + 1; set->num_cols = max_col - min_col + 1; return(0);}static int QccWAVbisk3DSetSize(QccWAVbisk3DSet *set, const QccWAVSubbandPyramid3D *coefficients, const QccWAVSubbandPyramid3D *mask, int subband){ int return_value; if (QccWAVSubbandPyramid3DSubbandOffsets(coefficients, subband, &set->origin_frame, &set->origin_row, &set->origin_col)) { QccErrorAddMessage("(QccWAVbisk3DSetSize): Error calling QccWAVSubbandPyramid3DSubbandOffsets()"); return(1); } if (QccWAVSubbandPyramid3DSubbandSize(coefficients, subband, &set->num_frames, &set->num_rows, &set->num_cols)) { QccErrorAddMessage("(QccWAVbisk3DSetSize): Error calling QccWAVSubbandPyramid3DSubbandSize()"); return(1); } return_value = QccWAVbisk3DSetShrink(set, mask); if (return_value == 2) return(2); else if (return_value == 1) { QccErrorAddMessage("(QccWAVbisk3DSetSize): Error calling QccWAVbisk3DSetShrink()"); return(1); } return(0);}static int QccWAVbisk3DLengthenLIS(QccList *LIS){ QccList new_list; QccListNode *new_list_node; QccListInitialize(&new_list); if ((new_list_node = QccListCreateNode(sizeof(QccList), &new_list)) == NULL) { QccErrorAddMessage("(QccWAVbisk3DLengthenLIS): Error calling QccListCreateNode()"); return(1); } if (QccListAppendNode(LIS, new_list_node)) { QccErrorAddMessage("(QccWAVbisk3DLengthenLIS): Error calling QccListAppendNode()"); return(1); } return(0);}static int QccWAVbisk3DInsertSet(QccList *LIS, QccListNode *set_node, QccListNode **list_node){ QccWAVbisk3DSet *set = (QccWAVbisk3DSet *)(set_node->value); QccListNode *current_list_node; QccList *current_list; int splits; current_list_node = LIS->start; for (splits = set->temporal_splits + set->horizontal_splits + set->vertical_splits; splits >= 0; splits--) { if (current_list_node->next == NULL) if (QccWAVbisk3DLengthenLIS(LIS)) { QccErrorAddMessage("(QccWAVbisk3DInsertSet): Error calling QccWAVbisk3DLengthenLIS()"); return(1); } current_list_node = current_list_node->next; } current_list = (QccList *)(current_list_node->value); if (QccListAppendNode(current_list, set_node)) { QccErrorAddMessage("(QccWAVbisk3DInsertSet): Error calling QccListAppendNode()"); return(1); } if (list_node != NULL) *list_node = current_list_node; return(0);}static int QccWAVbisk3DInitialization(QccList *LIS, QccList *LSP, const QccWAVSubbandPyramid3D *coefficients, const QccWAVSubbandPyramid3D *mask){ QccWAVbisk3DSet set; QccListNode *set_node; int subband; int num_subbands; int return_value; int horizontal_splits = 0; int temporal_splits = 0; if (coefficients->transform_type == QCCWAVSUBBANDPYRAMID3D_DYADIC) num_subbands = QccWAVSubbandPyramid3DNumLevelsToNumSubbandsDyadic(coefficients->spatial_num_levels); else num_subbands = QccWAVSubbandPyramid3DNumLevelsToNumSubbandsPacket(coefficients->temporal_num_levels, coefficients->spatial_num_levels); if (QccWAVbisk3DLengthenLIS(LIS)) { QccErrorAddMessage("(QccWAVbisk3DInitialization): Error calling QccWAVbisk3DLengthenLIS()"); return(1); } for (subband = 0; subband < num_subbands; subband++) { if (coefficients->transform_type == QCCWAVSUBBANDPYRAMID3D_PACKET) { if (QccWAVSubbandPyramid3DCalcLevelFromSubbandPacket(subband, coefficients->temporal_num_levels, coefficients->spatial_num_levels, &temporal_splits, &horizontal_splits)) { QccErrorAddMessage("(QccWAVbisk3DInitialization): Error calling QccWAVSubbandPyramid3DCalcLevelFromSubbandPacket()"); return(1); } set.temporal_splits = temporal_splits; set.horizontal_splits = horizontal_splits; set.vertical_splits = set.horizontal_splits; } else { set.horizontal_splits = QccWAVSubbandPyramid3DCalcLevelFromSubbandDyadic(subband, coefficients->spatial_num_levels); set.temporal_splits = set.horizontal_splits; set.vertical_splits = set.horizontal_splits; } set.significance = QCCBISK3D_INSIGNIFICANT; return_value = QccWAVbisk3DSetSize(&set, coefficients,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -