Commit 3bacd054 authored by Moritz Hanke's avatar Moritz Hanke

removes unused files

parent 8a21ea4b
#define B1 (0x0001)
#define B2 (0x0003)
#define B3 (0x0007)
#define B4 (0x000F)
#define B5 (0x001F)
#define B6 (0x003F)
#define B7 (0x007F)
#define B8 (0x00FF)
#define B9 (0x01FF)
#define B10 (0x03FF)
#define B11 (0x07FF)
#define B12 (0x0FFF)
#define B13 (0x1FFF)
#define B14 (0x3FFF)
#define B15 (0x7FFF)
#define B16 (0xFFFF)
// Copyright © 2011 Moritz Hanke
// Based on Lossless Data Compression. Blue Book. Issue 1. May 1997.
// CCSDS 121.0-B-1
//
// http://public.ccsds.org/publications/bluebooks.aspx
// http://public.ccsds.org/publications/archive/121x0b1c2.pdf
// Compression Identification Packet (optinal)
// The CIP is used to configure the decompressor in case no configuration
// data is available.
// It is comprised of the cip Primary Header (as described in "CCSDS Space
// Packet Protocol Blue Book") and the Packet Data Field.
enum cip_packet_type {
TELEMETRY, // reporting
TELECOMMAND, // requesting (makes no sense for compression)
};
enum cip_sequence_flag {
CONTINUE = 0,
FIRST = 1,
LAST = 2,
UNSEGMENTED = 3,
};
enum cip_compression_technique {
NO = 0, // no compression is used
LOSSLESS = 1, // lossless compression is used
};
enum cip_predictor_type {
BYPASS_P = 0, // bypass predictor
UNIT_DELAY_P = 1, // unit delay predictor
APP_SPECIFIC_P = 7, // application-specific predictor
};
enum cip_mapper_type {
STANDARD_M = 0, // standard prediction error mapper as described in the reference
APP_SPECIFIC_M = 3, // application-specific mapper
};
enum cip_data_sense {
TWOS_COMPLEMENT = 0, // two's complement
POSITIVE = 1, // positive (mandatory if preprocessor is bypassed)
};
enum entropy_coder_option {
OPTION_S = 1, // for resolution n <= 8
OPTION_M = 2, // for resolution 8 < n <= 16
OPTION_L = 3, // for resolution 16 < n <= 32
};
struct cip_header {
//----------------------------
// Packet Primary Header data
//----------------------------
char packet_version_number; // Packet Version Number
// Packet Identification
enum cip_packet_type type; // Packet Type
char secondary_header_available; // Sequence Header Flag
unsigned apid; // Application Process Identifier
// Packet Sequence Control
enum cip_sequence_flag sequence_flag; // Sequence Flags
unsigned sequence_count; // Packet Sequence Count
// in case of a TELECOMMAND type cip
// data package this contains the
// Packet Name
unsigned data_length; // length of the Packet Data Field - 1 in byte
};
struct cip_preprocessor_configuration {
char preprocessor_present; // Preprocessor Status (0 - absent, 1 - present)
enum cip_predictor_type predictor_type; // Predictor type (undefined if preprocessor is absent)
enum cip_mapper_type mapper_type; // Mapper type (undefined if preprocessor is absent)
char block_size; // Block size (8, 16 or application specific)
enum cip_data_sense data_sense;
char resolution; // Input data sample resolution (1-32)
};
struct cip_entropy_coder_configuration {
enum entropy_coder_option option; // Entropy Coder option
unsigned num_cds_per_packet; // Number of coded data sets per packet
};
struct cip_source_data_field {
unsigned grouping_data_length; // Grouping Data Length
enum cip_compression_technique compression_technique; // Compression Technique Identification
unsigned reference_sample_interval; // Reference Sample Interval
// - in case a preprocessor is
// used that requires a
// reference sample
// - in case of the zero-block
// option it contains the
// interval of input data sample
// blocks
struct cip_preprocessor_configuration preprocessor_config; // Preprocessor Configuration
struct cip_entropy_coder_configuration entropy_coder_config; // Entropy Coder Configuration
};
struct cip {
struct cip_header header; // Information from the Primary Header
struct cip_source_data_field sdf; // Information on the data
};
void * decode_cip(void * buffer, struct cip * cip);
// data: buffer starting with a cip
// cip: in case cip is not NULL the configuration information
// contained in the cip is written to it
// returns a pointer to the compressed data without the cip
// returns NULL in case an error occured while decoding
// Copyright 2011 Moritz Hanke
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "bit_macros.h"
#include "cip.h"
// decode Packet Primary Header
void * decode_pph(void * buffer, struct cip * cip);
// decode Secondary Header
void * decode_sh(void * buffer, struct cip * cip);
// decode Source Data Field
void * decode_sdf(void * buffer, struct cip * cip);
// decode Preprocessor Parameters
void * decode_preprocessor(void * buffer, struct cip * cip);
// decode Entopy Coder Parameters
void * decode_entropy_coder(void * buffer, struct cip * cip);
// decode Instrument Configuration
void * decode_instrument_configuration(void * buffer, struct cip * cip);
void * decode_cip(void * buffer, struct cip * cip) {
void * pdf; // Packet Data Field
void * sdf; // Source Data Field
void * cds; // Coded data sets
pdf = decode_pph(buffer, cip);
if (cip->header.secondary_header_available)
sdf = decode_sh(pdf, cip);
else
sdf = pdf;
cds = decode_sdf(sdf, cip);
if ((char*)cds > (char*)pdf + cip->header.data_length + 1) {
fprintf(stderr, "Packet Data Field is bigger than specified in CIP Packet Primary Header\n");
exit(EXIT_FAILURE);
}
return (char*)pdf + cip->header.data_length + 1;
}
// decode Primary Header
void * decode_pph(void * buffer, struct cip * cip) {
char * cip_buf = buffer;
// Packet Version Number
cip->header.packet_version_number = (cip_buf[0] >> 5) & B3 ;
if (cip->header.packet_version_number != 0) {
fprintf(stderr, "Undefined Packet Version Number\n");
exit(EXIT_FAILURE);
}
// Packet Identification
{
// Packet Type
cip->header.type = ((cip_buf[0] >> 4) & B1)?TELECOMMAND:TELEMETRY;
// is a Secondary Header available
cip->header.secondary_header_available = (cip_buf[0] >> 3) & B1;
// Application Process Identifer
cip->header.apid = ((unsigned)(cip_buf[0] & B3) << 8) | cip_buf[1];
}
// Packet Sequence Control
{
// Sequence Flags
cip->header.sequence_flag = (cip_buf[2] >> 6) & B2;
// Packet Sequence Count or Packet Name
assert(sizeof(unsigned) > 2);
cip->header.sequence_count = ((unsigned)(cip_buf[2] & B6) << 8) |
cip_buf[3];
}
// Packet Data Length
cip->header.data_length = ((unsigned)cip_buf[4] << 8) | cip_buf[5];
return (char*)cip + 6; // the Packet Primary Header has a size of 48
// bits
}
void * decode_sh(void * buffer, struct cip * cip) {
// The Secondary Header contains information like time and position
// or attitude of a spacecraft.
// The handling of a Secondary Header is currently not implemented.
fprintf(stderr, "Compression Identification Packet contains a Secondary Header\n");
exit(EXIT_FAILURE);
return buffer;
}
void * decode_sdf(void * buffer, struct cip * cip) {
char * sdf = buffer;
// Grouping Data Length (number of packets containing compressed data)
cip->sdf.grouping_data_length = (((unsigned)(sdf[0] & B4) << 8) |
sdf[1]) + 1;
// check whether a compression is used for the current group
if (sdf[2] > 1) {
fprintf(stderr, "Undefined compression technique\n");
exit(EXIT_FAILURE);
}
cip->sdf.compression_technique = sdf[2];
// Reference Sample Interval
cip->sdf.reference_sample_interval = sdf[3]+1;
if (cip->sdf.compression_technique == LOSSLESS) {
// decode Preprocessor Parameters
sdf = decode_preprocessor(sdf, cip);
}
// decode Entropy Coder Parameters
sdf = decode_entropy_coder(sdf, cip);
// decode Instrument Configuration
sdf = decode_instrument_configuration(sdf, cip);
return sdf;
}
void * decode_preprocessor(void * buffer, struct cip * cip) {
char * sdf = buffer;
unsigned header;
// check for correct header
header = (sdf[0] >> 6) & B2;
if (header != 0) {
fprintf(stderr, "Wrong header for preprocessor field\n");
exit(EXIT_FAILURE);
}
// get preprocessor presents
cip->sdf.preprocessor_config.preprocessor_present = (sdf[0] >> 5) & B1;
// if a preprocessor is present
if (cip->sdf.preprocessor_config.preprocessor_present) {
// Predictor type
switch ((sdf[0] >> 2) & B3) {
case (0):
cip->sdf.preprocessor_config.predictor_type = BYPASS_P;
break;
case (1):
cip->sdf.preprocessor_config.predictor_type = UNIT_DELAY_P;
break;
case (7):
cip->sdf.preprocessor_config.predictor_type = APP_SPECIFIC_P;
break;
default:
fprintf(stderr, "Invalid predictor type\n");
exit(EXIT_FAILURE);
};
// Mapper type
switch (sdf[0] & B2) {
case (0):
cip->sdf.preprocessor_config.mapper_type = STANDARD_M;
break;
case (3):
cip->sdf.preprocessor_config.mapper_type = APP_SPECIFIC_M;
break;
default:
fprintf(stderr, "Invalid mapper type\n");
exit(EXIT_FAILURE);
};
}
// Block size (J)
switch ((sdf[1] >> 6) & B2) {
case (0):
cip->sdf.preprocessor_config.block_size = 8;
break;
case (1):
cip->sdf.preprocessor_config.block_size = 16;
break;
case(3):
fprintf(stderr, "Missing implementation for application-specific block size\n");
exit(EXIT_FAILURE);
default:
fprintf(stderr, "Invalid block size\n");
exit(EXIT_FAILURE);
};
// Data sense
cip->sdf.preprocessor_config.data_sense = (sdf[1] >> 5) & 1;
// check whether preprocessor presents and data sense match
if (!cip->sdf.preprocessor_config.preprocessor_present &&
cip->sdf.preprocessor_config.data_sense != POSITIVE) {
fprintf(stderr, "If no preprocessor is present, the data sense has to be positive.\n");
exit(EXIT_FAILURE);
}
// Input data sample resolution
cip->sdf.preprocessor_config.resolution = (sdf[1] & B5) + 1;
return (char*)buffer + 2; // the preprocessor field has a size of 2 byte
}
void * decode_entropy_coder(void * buffer, struct cip * cip) {
char * sdf = buffer;
unsigned header;
// check for correct header
header = (sdf[0] >> 6) & B2;
if (header != 1) {
fprintf(stderr, "Wrong header for entropy coder field\n");
exit(EXIT_FAILURE);
}
// Entropy Coder option
switch ((sdf[0] >> 4) & B2) {
case (1):
if (cip->sdf.preprocessor_config.resolution > 8) {
fprintf(stderr, "Entropy coder option does not match input data sample resolution\n");
exit(EXIT_FAILURE);
}
cip->sdf.entropy_coder_config.option = OPTION_S;
break;
case (2):
if ((cip->sdf.preprocessor_config.resolution <= 8) ||
(cip->sdf.preprocessor_config.resolution > 16)) {
fprintf(stderr, "Entropy coder option does not match input data sample resolution\n");
exit(EXIT_FAILURE);
}
cip->sdf.entropy_coder_config.option = OPTION_M;
break;
case (3):
if ((cip->sdf.preprocessor_config.resolution <= 16) ||
(cip->sdf.preprocessor_config.resolution > 32)) {
fprintf(stderr, "Entropy coder option does not match input data sample resolution\n");
exit(EXIT_FAILURE);
}
cip->sdf.entropy_coder_config.option = OPTION_L;
break;
default:
fprintf(stderr, "Invalid entropy coder option\n");
exit(EXIT_FAILURE);
};
assert(sizeof(unsigned) > 2);
// Number of coded data sets per packet
cip->sdf.entropy_coder_config.num_cds_per_packet =
(((unsigned)(sdf[0] & B4) << 8) | sdf[1]) + 1;
return (char*)buffer + 2; // entropy coder field has a size of 2 byte
}
void * decode_instrument_configuration(void * buffer, struct cip * cip) {
// Instrument Configuration is mission specific.
// This implementation assumes that there is no.
// In an one is added later, the first 2 bits of buffer have to 10.
return buffer;
}
// Copyright 2011 Moritz Hanke
#include <stdlib.h>
#include "cip.h"
int main() {
return EXIT_SUCCESS;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment