?? bisk.c
字號:
/* * * QccPack: Quantization, compression, and coding libraries * Copyright (C) 1997-2005 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 QCCBISK_BOUNDARY_VALUE 0#define QCCBISK_INSIGNIFICANT 0#define QCCBISK_SIGNIFICANT 1#define QCCBISK_NEWLY_SIGNIFICANT 2#define QCCBISK_EMPTYSET 3#define QCCBISK_POSITIVE 0#define QCCBISK_NEGATIVE 1#define QCCBISK_MAXBITPLANES 128#define QCCBISK_CONTEXT_NOCODE -1#define QCCBISK_CONTEXT_SIGNIFICANCE 0#define QCCBISK_CONTEXT_SIGNIFICANCE_SUBSET1 1#define QCCBISK_CONTEXT_SIGNIFICANCE_SUBSET2 2#define QCCBISK_CONTEXT_SIGN 3#define QCCBISK_CONTEXT_REFINEMENT 4#define QCCBISK_NUM_CONTEXTS 5static const int QccWAVbiskNumSymbols[] = { 2, 2, 2, 2, 2 };typedef struct{ int level; int origin_row; int origin_col; int num_rows; int num_cols; char significance;} QccWAVbiskSet;typedef struct{ QccWAVSubbandPyramid original_coefficients; QccWAVSubbandPyramid reconstructed_coefficients; QccWAVSubbandPyramid squared_errors; double distortion; int num_pixels; int start_position; FILE *file;} QccWAVbiskDistortionTrace;static int QccWAVbiskTransparent(const QccWAVSubbandPyramid *mask, int row, int col){ if (mask == NULL) return(0); return(QccAlphaTransparent(mask->matrix[row][col]));}static void QccWAVbiskDistortionTraceInitialize(QccWAVbiskDistortionTrace *distortion_trace, QccWAVSubbandPyramid *original_coefficients, QccWAVSubbandPyramid *mask, QccBitBuffer *output_buffer, FILE *outfile){ int row, col; QccWAVSubbandPyramidInitialize(&distortion_trace->original_coefficients); QccWAVSubbandPyramidInitialize(&distortion_trace->reconstructed_coefficients); QccWAVSubbandPyramidInitialize(&distortion_trace->squared_errors); QccWAVSubbandPyramidCopy(&distortion_trace->original_coefficients, original_coefficients); QccWAVSubbandPyramidCopy(&distortion_trace->reconstructed_coefficients, original_coefficients); QccWAVSubbandPyramidCopy(&distortion_trace->squared_errors, original_coefficients); QccMatrixZero(distortion_trace->reconstructed_coefficients.matrix, distortion_trace->reconstructed_coefficients.num_rows, distortion_trace->reconstructed_coefficients.num_cols); distortion_trace->distortion = 0; distortion_trace->num_pixels = 0; distortion_trace->start_position = output_buffer->bit_cnt; for (row = 0; row < distortion_trace->squared_errors.num_rows; row++) for (col = 0; col < distortion_trace->squared_errors.num_cols; col++) if (!QccWAVbiskTransparent(mask, row, col)) { distortion_trace->squared_errors.matrix[row][col] *= distortion_trace->squared_errors.matrix[row][col]; distortion_trace->distortion += distortion_trace->squared_errors.matrix[row][col]; distortion_trace->num_pixels++; } distortion_trace->file = outfile; fprintf(outfile, " Rate (bpp)\t MSE\n"); fprintf(outfile, "--------------------------------------------\n");}static void QccWAVbiskDistortionTraceUpdate(QccWAVbiskDistortionTrace *distortion_trace, int row, int col, QccBitBuffer *buffer){ double diff; QccMatrix original_coefficients = distortion_trace->original_coefficients.matrix; QccMatrix reconstructed_coefficients = distortion_trace->reconstructed_coefficients.matrix; QccMatrix squared_errors = distortion_trace->squared_errors.matrix; distortion_trace->distortion -= squared_errors[row][col]; diff = original_coefficients[row][col] - reconstructed_coefficients[row][col]; squared_errors[row][col] = diff * diff; distortion_trace->distortion += squared_errors[row][col]; fprintf(distortion_trace->file, "%16.6f\t%16.6f\n", (double)(buffer->bit_cnt - distortion_trace->start_position) / distortion_trace->num_pixels, distortion_trace->distortion / distortion_trace->num_pixels);}static int QccWAVbiskSetIsPixel(QccWAVbiskSet *set){ if ((set->num_rows == 1) && (set->num_cols == 1)) return(1); return(0);}#if 0static void QccWAVbiskSetPrint(const QccWAVbiskSet *set){ printf("<%d,%d,%d,%d,%d,%c>\n", set->level, set->origin_row, set->origin_col, set->num_rows, set->num_cols, ((set->significance == QCCBISK_INSIGNIFICANT) ? 'i' : ((set->significance == QCCBISK_SIGNIFICANT) ? 's' : 'S')));}static void QccWAVbiskLISPrint(const QccList *LIS){ QccListNode *current_list_node; QccList *current_list; QccListNode *current_set_node; QccWAVbiskSet *current_set; int level = 0; printf("LIS:\n"); current_list_node = LIS->start; while (current_list_node != NULL) { printf("Level %d:\n", level++); current_list = (QccList *)(current_list_node->value); current_set_node = current_list->start; while (current_set_node != NULL) { current_set = (QccWAVbiskSet *)(current_set_node->value); QccWAVbiskSetPrint(current_set); current_set_node = current_set_node->next; } current_list_node = current_list_node->next; } printf("===============================================\n"); fflush(stdout);}static void QccWAVbiskLSPPrint(const QccList *LSP){ QccListNode *current_set_node; QccWAVbiskSet *current_set; printf("LSP:\n"); current_set_node = LSP->start; while (current_set_node != NULL) { current_set = (QccWAVbiskSet *)(current_set_node->value); QccWAVbiskSetPrint(current_set); current_set_node = current_set_node->next; } printf("===============================================\n"); fflush(stdout);}#endifstatic int QccWAVbiskSetShrink(QccWAVbiskSet *set, const QccWAVSubbandPyramid *mask){ int row; int col; int min_row = MAXINT; int min_col = MAXINT; int max_row = -MAXINT; int max_col = -MAXINT; int totally_transparent = 1; if (mask == NULL) { if ((!set->num_rows) || (!set->num_cols)) return(2); else return(0); } for (row = 0; row < set->num_rows; row++) for (col = 0; col < set->num_cols; col++) if (!QccWAVbiskTransparent(mask, row + set->origin_row, col + set->origin_col)) { totally_transparent = 0; max_row = QccMathMax(max_row, row + set->origin_row); max_col = QccMathMax(max_col, col + set->origin_col); 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_row = min_row; set->origin_col = min_col; set->num_rows = max_row - min_row + 1; set->num_cols = max_col - min_col + 1; return(0);}static int QccWAVbiskSetSize(QccWAVbiskSet *set, const QccWAVSubbandPyramid *coefficients, const QccWAVSubbandPyramid *mask, int subband){ int return_value; if (QccWAVSubbandPyramidSubbandOffsets(coefficients, subband, &set->origin_row, &set->origin_col)) { QccErrorAddMessage("(QccWAVbiskSetSize): Error calling QccWAVSubbandPyramidSubbandOffsets()"); return(1); } if (QccWAVSubbandPyramidSubbandSize(coefficients, subband, &set->num_rows, &set->num_cols)) { QccErrorAddMessage("(QccWAVbiskSetSize): Error calling QccWAVSubbandPyramidSubbandSize()"); return(1); } return_value = QccWAVbiskSetShrink(set, mask); if (return_value == 2) return(2); else if (return_value == 1) { QccErrorAddMessage("(QccWAVbiskSetSize): Error calling QccWAVShapeAdaptiveMaskBoundingBox()"); return(1); } return(0);}static int QccWAVbiskLengthenLIS(QccList *LIS){ QccList new_list; QccListNode *new_list_node; QccListInitialize(&new_list); if ((new_list_node = QccListCreateNode(sizeof(QccList), &new_list)) == NULL) { QccErrorAddMessage("(QccWAVbiskLengthenLIS): Error calling QccListCreateNode()"); return(1); } if (QccListAppendNode(LIS, new_list_node)) { QccErrorAddMessage("(QccWAVbiskLengthenLIS): Error calling QccListAppendNode()"); return(1); } return(0);}static int QccWAVbiskInsertSet(QccList *LIS, QccWAVbiskSet *set, QccListNode **list_node, QccListNode **set_node){ QccListNode *new_set_node; QccListNode *current_list_node; QccList *current_list; int level; if ((new_set_node = QccListCreateNode(sizeof(QccWAVbiskSet), set)) == NULL) { QccErrorAddMessage("(QccWAVbiskInsertSet): Error calling QccListCreateNode()"); return(1); } current_list_node = LIS->start; for (level = set->level; (current_list_node != NULL) && level; level--) { if (current_list_node->next == NULL) if (QccWAVbiskLengthenLIS(LIS)) { QccErrorAddMessage("(QccWAVbiskInsertSet): Error calling QccWAVbiskLengthenLIS()"); return(1); } current_list_node = current_list_node->next; } current_list = (QccList *)(current_list_node->value); if (QccListAppendNode(current_list, new_set_node)) { QccErrorAddMessage("(QccWAVbiskInsertSet): Error calling QccListAppendNode()"); return(1); } if (set_node != NULL) *set_node = new_set_node; if (list_node != NULL) *list_node = current_list_node; return(0);}static int QccWAVbiskInitialization(QccList *LIS, QccList *LSP, const QccWAVSubbandPyramid *coefficients, const QccWAVSubbandPyramid *mask){ QccWAVbiskSet set; int subband; int num_subbands; int return_value; num_subbands =
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -