mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2024-12-24 20:01:42 +00:00
output of dvb in srt sami smptett format
This commit is contained in:
parent
45d1dfe425
commit
c054594383
150
src/608_sami.c
150
src/608_sami.c
@ -1,6 +1,9 @@
|
||||
#include "ccextractor.h"
|
||||
#include "cc_encoders_common.h"
|
||||
|
||||
#include "png.h"
|
||||
#include "spupng_encoder.h"
|
||||
#include "ocr.h"
|
||||
#include "utility.h"
|
||||
void write_stringz_as_sami(char *string, struct encoder_ctx *context, LLONG ms_start, LLONG ms_end)
|
||||
{
|
||||
int used;
|
||||
@ -74,7 +77,152 @@ void write_stringz_as_sami(char *string, struct encoder_ctx *context, LLONG ms_s
|
||||
}
|
||||
|
||||
|
||||
int write_cc_bitmap_as_sami(struct cc_subtitle *sub, struct encoder_ctx *context)
|
||||
{
|
||||
struct spupng_t *sp = (struct spupng_t *)context->out->spupng_data;
|
||||
int x_pos, y_pos, width, height, i;
|
||||
int x, y, y_off, x_off, ret;
|
||||
uint8_t *pbuf;
|
||||
char *filename;
|
||||
struct cc_bitmap* rect;
|
||||
png_color *palette = NULL;
|
||||
png_byte *alpha = NULL;
|
||||
#ifdef ENABLE_OCR
|
||||
char*str = NULL;
|
||||
#endif
|
||||
int used;
|
||||
unsigned h1,m1,s1,ms1;
|
||||
unsigned h2,m2,s2,ms2;
|
||||
LLONG ms_start, ms_end;
|
||||
char timeline[128];
|
||||
int len = 0;
|
||||
|
||||
x_pos = -1;
|
||||
y_pos = -1;
|
||||
width = 0;
|
||||
height = 0;
|
||||
|
||||
if (context->prev_start != -1 && (sub->flags & SUB_EOD_MARKER))
|
||||
{
|
||||
ms_start = context->prev_start + subs_delay;
|
||||
ms_end = sub->start_time - 1;
|
||||
}
|
||||
else if ( !(sub->flags & SUB_EOD_MARKER))
|
||||
{
|
||||
ms_start = sub->start_time + subs_delay;
|
||||
ms_end = sub->end_time - 1;
|
||||
}
|
||||
|
||||
if(sub->nb_data == 0 )
|
||||
return 0;
|
||||
rect = sub->data;
|
||||
for(i = 0;i < sub->nb_data;i++)
|
||||
{
|
||||
if(x_pos == -1)
|
||||
{
|
||||
x_pos = rect[i].x;
|
||||
y_pos = rect[i].y;
|
||||
width = rect[i].w;
|
||||
height = rect[i].h;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(x_pos > rect[i].x)
|
||||
{
|
||||
width += (x_pos - rect[i].x);
|
||||
x_pos = rect[i].x;
|
||||
}
|
||||
|
||||
if (rect[i].y < y_pos)
|
||||
{
|
||||
height += (y_pos - rect[i].y);
|
||||
y_pos = rect[i].y;
|
||||
}
|
||||
|
||||
if (rect[i].x + rect[i].w > x_pos + width)
|
||||
{
|
||||
width = rect[i].x + rect[i].w - x_pos;
|
||||
}
|
||||
|
||||
if (rect[i].y + rect[i].h > y_pos + height)
|
||||
{
|
||||
height = rect[i].y + rect[i].h - y_pos;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if ( sub->flags & SUB_EOD_MARKER )
|
||||
context->prev_start = sub->start_time;
|
||||
pbuf = (uint8_t*) malloc(width * height);
|
||||
memset(pbuf, 0x0, width * height);
|
||||
|
||||
for(i = 0;i < sub->nb_data;i++)
|
||||
{
|
||||
x_off = rect[i].x - x_pos;
|
||||
y_off = rect[i].y - y_pos;
|
||||
for (y = 0; y < rect[i].h; y++)
|
||||
{
|
||||
for (x = 0; x < rect[i].w; x++)
|
||||
pbuf[((y + y_off) * width) + x_off + x] = rect[i].data[0][y * rect[i].w + x];
|
||||
|
||||
}
|
||||
}
|
||||
palette = (png_color*) malloc(rect[0].nb_colors * sizeof(png_color));
|
||||
if(!palette)
|
||||
{
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
alpha = (png_byte*) malloc(rect[0].nb_colors * sizeof(png_byte));
|
||||
if(!alpha)
|
||||
{
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
/* TODO do rectangle, wise one color table should not be used for all rectangle */
|
||||
mapclut_paletee(palette, alpha, (uint32_t *)rect[0].data[1],rect[0].nb_colors);
|
||||
quantize_map(alpha, palette, pbuf, width*height, 3, rect[0].nb_colors);
|
||||
#ifdef ENABLE_OCR
|
||||
str = ocr_bitmap(palette,alpha,pbuf,width,height);
|
||||
if(str && str[0])
|
||||
{
|
||||
if (context->prev_start != -1 || !(sub->flags & SUB_EOD_MARKER))
|
||||
{
|
||||
char *token = NULL;
|
||||
sprintf(context->buffer,
|
||||
"<SYNC start=%llu><P class=\"UNKNOWNCC\">\r\n"
|
||||
,(unsigned long long)ms_start);
|
||||
write(context->out->fh,context->buffer,strlen(context->buffer));
|
||||
token = strtok(str,"\r\n");
|
||||
while (token)
|
||||
{
|
||||
|
||||
sprintf(context->buffer,"%s",token);
|
||||
token = strtok(NULL,"\r\n");
|
||||
if(token)
|
||||
strcat(context->buffer,"<br>\n");
|
||||
else
|
||||
strcat(context->buffer,"\n");
|
||||
write(context->out->fh,context->buffer,strlen(context->buffer));
|
||||
|
||||
}
|
||||
sprintf(context->buffer,
|
||||
"<SYNC start=%llu><P class=\"UNKNOWNCC\"> </P></SYNC>\r\n\r\n"
|
||||
,(unsigned long long)ms_end);
|
||||
write(context->out->fh,context->buffer,strlen(context->buffer));
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
end:
|
||||
sub->nb_data = 0;
|
||||
freep(&sub->data);
|
||||
freep(&palette);
|
||||
freep(&alpha);
|
||||
return ret;
|
||||
|
||||
}
|
||||
int write_cc_buffer_as_sami(struct eia608_screen *data, struct encoder_ctx *context)
|
||||
{
|
||||
int used;
|
||||
|
@ -1,5 +1,9 @@
|
||||
#include "ccextractor.h"
|
||||
#include "cc_encoders_common.h"
|
||||
#include "png.h"
|
||||
#include "spupng_encoder.h"
|
||||
#include "ocr.h"
|
||||
#include "utility.h"
|
||||
|
||||
// Produces minimally-compliant SMPTE Timed Text (W3C TTML)
|
||||
// format-compatible output
|
||||
@ -99,6 +103,138 @@ void write_stringz_as_smptett(char *string, struct encoder_ctx *context, LLONG m
|
||||
}
|
||||
|
||||
|
||||
int write_cc_bitmap_as_smptett(struct cc_subtitle *sub, struct encoder_ctx *context)
|
||||
{
|
||||
struct spupng_t *sp = (struct spupng_t *)context->out->spupng_data;
|
||||
int x_pos, y_pos, width, height, i;
|
||||
int x, y, y_off, x_off, ret;
|
||||
uint8_t *pbuf;
|
||||
char *filename;
|
||||
struct cc_bitmap* rect;
|
||||
png_color *palette = NULL;
|
||||
png_byte *alpha = NULL;
|
||||
#ifdef ENABLE_OCR
|
||||
char*str = NULL;
|
||||
#endif
|
||||
int used;
|
||||
unsigned h1,m1,s1,ms1;
|
||||
unsigned h2,m2,s2,ms2;
|
||||
LLONG ms_start, ms_end;
|
||||
char timeline[128];
|
||||
int len = 0;
|
||||
|
||||
x_pos = -1;
|
||||
y_pos = -1;
|
||||
width = 0;
|
||||
height = 0;
|
||||
|
||||
if (context->prev_start != -1 && (sub->flags & SUB_EOD_MARKER))
|
||||
{
|
||||
ms_start = context->prev_start + subs_delay;
|
||||
ms_end = sub->start_time - 1;
|
||||
}
|
||||
else if ( !(sub->flags & SUB_EOD_MARKER))
|
||||
{
|
||||
ms_start = sub->start_time + subs_delay;
|
||||
ms_end = sub->end_time - 1;
|
||||
}
|
||||
|
||||
if(sub->nb_data == 0 )
|
||||
return 0;
|
||||
rect = sub->data;
|
||||
for(i = 0;i < sub->nb_data;i++)
|
||||
{
|
||||
if(x_pos == -1)
|
||||
{
|
||||
x_pos = rect[i].x;
|
||||
y_pos = rect[i].y;
|
||||
width = rect[i].w;
|
||||
height = rect[i].h;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(x_pos > rect[i].x)
|
||||
{
|
||||
width += (x_pos - rect[i].x);
|
||||
x_pos = rect[i].x;
|
||||
}
|
||||
|
||||
if (rect[i].y < y_pos)
|
||||
{
|
||||
height += (y_pos - rect[i].y);
|
||||
y_pos = rect[i].y;
|
||||
}
|
||||
|
||||
if (rect[i].x + rect[i].w > x_pos + width)
|
||||
{
|
||||
width = rect[i].x + rect[i].w - x_pos;
|
||||
}
|
||||
|
||||
if (rect[i].y + rect[i].h > y_pos + height)
|
||||
{
|
||||
height = rect[i].y + rect[i].h - y_pos;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if ( sub->flags & SUB_EOD_MARKER )
|
||||
context->prev_start = sub->start_time;
|
||||
pbuf = (uint8_t*) malloc(width * height);
|
||||
memset(pbuf, 0x0, width * height);
|
||||
|
||||
for(i = 0;i < sub->nb_data;i++)
|
||||
{
|
||||
x_off = rect[i].x - x_pos;
|
||||
y_off = rect[i].y - y_pos;
|
||||
for (y = 0; y < rect[i].h; y++)
|
||||
{
|
||||
for (x = 0; x < rect[i].w; x++)
|
||||
pbuf[((y + y_off) * width) + x_off + x] = rect[i].data[0][y * rect[i].w + x];
|
||||
|
||||
}
|
||||
}
|
||||
palette = (png_color*) malloc(rect[0].nb_colors * sizeof(png_color));
|
||||
if(!palette)
|
||||
{
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
alpha = (png_byte*) malloc(rect[0].nb_colors * sizeof(png_byte));
|
||||
if(!alpha)
|
||||
{
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
/* TODO do rectangle, wise one color table should not be used for all rectangle */
|
||||
mapclut_paletee(palette, alpha, (uint32_t *)rect[0].data[1],rect[0].nb_colors);
|
||||
quantize_map(alpha, palette, pbuf, width*height, 3, rect[0].nb_colors);
|
||||
#ifdef ENABLE_OCR
|
||||
str = ocr_bitmap(palette,alpha,pbuf,width,height);
|
||||
if(str && str[0])
|
||||
{
|
||||
if (context->prev_start != -1 || !(sub->flags & SUB_EOD_MARKER))
|
||||
{
|
||||
mstotime (ms_start,&h1,&m1,&s1,&ms1);
|
||||
mstotime (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
|
||||
sprintf ((char *) context->buffer,"<p begin=\"%02u:%02u:%02u,%03u\" end=\"%02u:%02u:%02u,%03u\">\n",h1,m1,s1,ms1, h2,m2,s2,ms2);
|
||||
write (context->out->fh, context->buffer,strlen(context->buffer) );
|
||||
len = strlen(str);
|
||||
write (context->out->fh, str, len);
|
||||
write (context->out->fh, encoded_crlf, encoded_crlf_length);
|
||||
sprintf ((char *) str,"</p>\n");
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
end:
|
||||
sub->nb_data = 0;
|
||||
freep(&sub->data);
|
||||
freep(&palette);
|
||||
freep(&alpha);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int write_cc_buffer_as_smptett(struct eia608_screen *data, struct encoder_ctx *context)
|
||||
{
|
||||
|
140
src/608_srt.c
140
src/608_srt.c
@ -1,5 +1,9 @@
|
||||
#include "ccextractor.h"
|
||||
#include "cc_encoders_common.h"
|
||||
#include "png.h"
|
||||
#include "spupng_encoder.h"
|
||||
#include "ocr.h"
|
||||
#include "utility.h"
|
||||
|
||||
/* The timing here is not PTS based, but output based, i.e. user delay must be accounted for
|
||||
if there is any */
|
||||
@ -68,6 +72,142 @@ void write_stringz_as_srt(char *string, struct encoder_ctx *context, LLONG ms_st
|
||||
free(unescaped);
|
||||
}
|
||||
|
||||
int write_cc_bitmap_as_srt(struct cc_subtitle *sub, struct encoder_ctx *context)
|
||||
{
|
||||
struct spupng_t *sp = (struct spupng_t *)context->out->spupng_data;
|
||||
int x_pos, y_pos, width, height, i;
|
||||
int x, y, y_off, x_off, ret;
|
||||
uint8_t *pbuf;
|
||||
char *filename;
|
||||
struct cc_bitmap* rect;
|
||||
png_color *palette = NULL;
|
||||
png_byte *alpha = NULL;
|
||||
#ifdef ENABLE_OCR
|
||||
char*str = NULL;
|
||||
#endif
|
||||
int used;
|
||||
unsigned h1,m1,s1,ms1;
|
||||
unsigned h2,m2,s2,ms2;
|
||||
LLONG ms_start, ms_end;
|
||||
char timeline[128];
|
||||
int len = 0;
|
||||
|
||||
x_pos = -1;
|
||||
y_pos = -1;
|
||||
width = 0;
|
||||
height = 0;
|
||||
|
||||
if (context->prev_start != -1 && (sub->flags & SUB_EOD_MARKER))
|
||||
{
|
||||
ms_start = context->prev_start;
|
||||
ms_end = sub->start_time;
|
||||
}
|
||||
else if ( !(sub->flags & SUB_EOD_MARKER))
|
||||
{
|
||||
ms_start = sub->start_time;
|
||||
ms_end = sub->end_time;
|
||||
}
|
||||
|
||||
if(sub->nb_data == 0 )
|
||||
return 0;
|
||||
rect = sub->data;
|
||||
for(i = 0;i < sub->nb_data;i++)
|
||||
{
|
||||
if(x_pos == -1)
|
||||
{
|
||||
x_pos = rect[i].x;
|
||||
y_pos = rect[i].y;
|
||||
width = rect[i].w;
|
||||
height = rect[i].h;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(x_pos > rect[i].x)
|
||||
{
|
||||
width += (x_pos - rect[i].x);
|
||||
x_pos = rect[i].x;
|
||||
}
|
||||
|
||||
if (rect[i].y < y_pos)
|
||||
{
|
||||
height += (y_pos - rect[i].y);
|
||||
y_pos = rect[i].y;
|
||||
}
|
||||
|
||||
if (rect[i].x + rect[i].w > x_pos + width)
|
||||
{
|
||||
width = rect[i].x + rect[i].w - x_pos;
|
||||
}
|
||||
|
||||
if (rect[i].y + rect[i].h > y_pos + height)
|
||||
{
|
||||
height = rect[i].y + rect[i].h - y_pos;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if ( sub->flags & SUB_EOD_MARKER )
|
||||
context->prev_start = sub->start_time;
|
||||
pbuf = (uint8_t*) malloc(width * height);
|
||||
memset(pbuf, 0x0, width * height);
|
||||
|
||||
for(i = 0;i < sub->nb_data;i++)
|
||||
{
|
||||
x_off = rect[i].x - x_pos;
|
||||
y_off = rect[i].y - y_pos;
|
||||
for (y = 0; y < rect[i].h; y++)
|
||||
{
|
||||
for (x = 0; x < rect[i].w; x++)
|
||||
pbuf[((y + y_off) * width) + x_off + x] = rect[i].data[0][y * rect[i].w + x];
|
||||
|
||||
}
|
||||
}
|
||||
palette = (png_color*) malloc(rect[0].nb_colors * sizeof(png_color));
|
||||
if(!palette)
|
||||
{
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
alpha = (png_byte*) malloc(rect[0].nb_colors * sizeof(png_byte));
|
||||
if(!alpha)
|
||||
{
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
/* TODO do rectangle, wise one color table should not be used for all rectangle */
|
||||
mapclut_paletee(palette, alpha, (uint32_t *)rect[0].data[1],rect[0].nb_colors);
|
||||
quantize_map(alpha, palette, pbuf, width*height, 3, rect[0].nb_colors);
|
||||
#ifdef ENABLE_OCR
|
||||
str = ocr_bitmap(palette,alpha,pbuf,width,height);
|
||||
if(str && str[0])
|
||||
{
|
||||
if (context->prev_start != -1 || !(sub->flags & SUB_EOD_MARKER))
|
||||
{
|
||||
mstotime (ms_start,&h1,&m1,&s1,&ms1);
|
||||
mstotime (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
|
||||
context->srt_counter++;
|
||||
sprintf(timeline, "%u\r\n", context->srt_counter);
|
||||
used = encode_line(context->buffer,(unsigned char *) timeline);
|
||||
write(context->out->fh, context->buffer, used);
|
||||
sprintf (timeline, "%02u:%02u:%02u,%03u --> %02u:%02u:%02u,%03u\r\n",
|
||||
h1,m1,s1,ms1, h2,m2,s2,ms2);
|
||||
used = encode_line(context->buffer,(unsigned char *) timeline);
|
||||
write (context->out->fh, context->buffer, used);
|
||||
len = strlen(str);
|
||||
write (context->out->fh, str, len);
|
||||
write (context->out->fh, encoded_crlf, encoded_crlf_length);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
end:
|
||||
sub->nb_data = 0;
|
||||
freep(&sub->data);
|
||||
freep(&palette);
|
||||
freep(&alpha);
|
||||
return ret;
|
||||
|
||||
}
|
||||
int write_cc_buffer_as_srt(struct eia608_screen *data, struct encoder_ctx *context)
|
||||
{
|
||||
int used;
|
||||
|
@ -3,12 +3,6 @@
|
||||
|
||||
/* flag raised when end of display marker arrives in Dvb Subtitle */
|
||||
#define SUB_EOD_MARKER (1 << 0 )
|
||||
enum subtype
|
||||
{
|
||||
CC_BITMAP,
|
||||
CC_608,
|
||||
};
|
||||
|
||||
struct cc_bitmap
|
||||
{
|
||||
int x;
|
||||
|
@ -388,12 +388,22 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub)
|
||||
switch (ccx_options.write_format)
|
||||
{
|
||||
case CCX_OF_SRT:
|
||||
if (!startcredits_displayed && ccx_options.start_credits_text!=NULL)
|
||||
try_to_add_start_credits(context, sub->start_time);
|
||||
wrote_something = write_cc_bitmap_as_srt(sub, context);
|
||||
case CCX_OF_SAMI:
|
||||
if (!startcredits_displayed && ccx_options.start_credits_text!=NULL)
|
||||
try_to_add_start_credits(context, sub->start_time);
|
||||
wrote_something = write_cc_bitmap_as_sami(sub, context);
|
||||
case CCX_OF_SMPTETT:
|
||||
if (!startcredits_displayed && ccx_options.start_credits_text!=NULL)
|
||||
try_to_add_start_credits(context, sub->start_time);
|
||||
wrote_something = write_cc_bitmap_as_smptett(sub, context);
|
||||
case CCX_OF_TRANSCRIPT:
|
||||
// wrote_something = write_cc_bitmap_as_transcript(sub, context);
|
||||
break;
|
||||
case CCX_OF_SPUPNG:
|
||||
write_cc_bitmap_as_spupng(sub, context);
|
||||
wrote_something = write_cc_bitmap_as_spupng(sub, context);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -61,4 +61,7 @@ void write_stringz_as_smptett(char *string, struct encoder_ctx *context, LLONG m
|
||||
void write_cc_buffer_to_gui(struct eia608_screen *data, struct encoder_ctx *context);
|
||||
|
||||
int write_cc_bitmap_as_spupng(struct cc_subtitle *sub, struct encoder_ctx *context);
|
||||
int write_cc_bitmap_as_srt(struct cc_subtitle *sub, struct encoder_ctx *context);
|
||||
int write_cc_bitmap_as_sami(struct cc_subtitle *sub, struct encoder_ctx *context);
|
||||
int write_cc_bitmap_as_smptett(struct cc_subtitle *sub, struct encoder_ctx *context);
|
||||
#endif
|
||||
|
@ -258,8 +258,11 @@ enum cxx_code_type
|
||||
#define CCX_TXT_AUTO_NOT_YET_FOUND 1
|
||||
#define CCX_TXT_IN_USE 2 // Positive autodetected, or forced, etc
|
||||
|
||||
|
||||
#define CCX_OF_TYPE_TEXT 1
|
||||
#define CCX_OF_TYPE_IMAGE 2
|
||||
enum subtype
|
||||
{
|
||||
CC_BITMAP,
|
||||
CC_608,
|
||||
CC_TEXT,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -317,10 +317,6 @@ void write_spucomment(struct spupng_t *sp,const char *str)
|
||||
fprintf(sp->fpxml, "-->\n");
|
||||
}
|
||||
|
||||
int get_spupng_subtype(void)
|
||||
{
|
||||
return (1 << CCX_OF_TYPE_TEXT)|(1<<CCX_OF_TYPE_IMAGE);
|
||||
}
|
||||
char* get_spupng_filename(void *ctx)
|
||||
{
|
||||
struct spupng_t *sp = (struct spupng_t *)ctx;
|
||||
|
@ -32,4 +32,8 @@ void write_spucomment(struct spupng_t *sp,const char *str);
|
||||
char* get_spupng_filename(void *ctx);
|
||||
void inc_spupng_fileindex(void *ctx);
|
||||
void set_spupng_offset(void *ctx,int x,int y);
|
||||
int mapclut_paletee(png_color *palette, png_byte *alpha, uint32_t *clut,
|
||||
uint8_t depth);
|
||||
int quantize_map(png_byte *alpha, png_color *palette,
|
||||
uint8_t *bitmap, int size, int max_color, int nb_color);
|
||||
#endif
|
||||
|
@ -267,11 +267,13 @@ int parse_PMT (unsigned char *buf,int len, int pos)
|
||||
{
|
||||
enum ccx_mpeg_descriptor descriptor_tag = (enum ccx_mpeg_descriptor)(*es_info++);
|
||||
desc_len = (*es_info++);
|
||||
#ifndef ENABLE_OCR
|
||||
if(ccx_options.write_format != CCX_OF_SPUPNG )
|
||||
{
|
||||
mprint ("DVB subtitle only support spupng type as output\n");
|
||||
mprint ("Please Compile with ENABLE_OCR flag \n");
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if(CCX_MPEG_DSC_DVB_SUBTITLE == descriptor_tag)
|
||||
{
|
||||
struct dvb_config cnf;
|
||||
|
@ -5,10 +5,6 @@
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define snprintf(str,size,format,...) _snprintf(str,size-1,format,__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define RL32(x) (*(unsigned int *)(x))
|
||||
#define RB32(x) (ntohl(*(unsigned int *)(x)))
|
||||
#define RL16(x) (*(unsigned short int*)(x))
|
||||
|
Loading…
Reference in New Issue
Block a user