Skip to content
Snippets Groups Projects
Commit 3bacd054 authored by Moritz Hanke's avatar Moritz Hanke
Browse files

removes unused files

parent 8a21ea4b
No related branches found
No related tags found
No related merge requests found
#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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment