Cameras axis retain some information as markers, but zm removes all markers during processing.
I tried to implement the preservation of markers in the processing, but did not succeed.
Perhaps the solution already exists?
How to keep all jpeg markers?
Re: How to keep all jpeg markers?
I implemented this feature. But I can not attach a diff file: "The extension diff is not allowed".
Re: How to keep all jpeg markers?
I can not even insert the code - "Your post looks too spamy for a new user, please remove off-site URLs. " In the code, there are no links, but there is JPEG_CОM.. (
Re: How to keep all jpeg markers?
At moonug's request, posting on their behalf.
Note: This is unchecked code, use at own risk;
Note: This is unchecked code, use at own risk;
Code: Select all
Code:
diff -ruw ZoneMinder-1.25.0/src/zm_image.cpp zm/src/zm_image.cpp
--- ZoneMinder-1.25.0/src/zm_image.cpp 2011-06-21 13:19:10.000000000 +0400
+++ zm/src/zm_image.cpp 2012-04-13 13:40:05.000000000 +0400
@@ -45,8 +45,10 @@
pixels = 0;
colours = 0;
size = 0;
+ markers_size = 0;
allocation = 0;
buffer = 0;
+ markers = 0;
blend_buffer = 0;
text[0] = '\0';
}
@@ -60,8 +62,10 @@
pixels = 0;
colours = 0;
size = 0;
+ markers_size = 0;
allocation = 0;
buffer = 0;
+ markers = 0;
ReadJpeg( filename );
blend_buffer = 0;
text[0] = '\0';
@@ -79,13 +83,15 @@
if ( p_buffer )
{
allocation = 0;
+ markers = p_buffer + size;
buffer = p_buffer;
}
else
{
- allocation = size;
+ allocation = size+JM_SIZE;
buffer = new uint8_t[allocation];
- memset( buffer, 0, size );
+ markers = buffer + size;
+ memset( buffer, 0, allocation );
}
blend_buffer = 0;
text[0] = '\0';
@@ -99,9 +105,11 @@
height = p_image.height;
pixels = p_image.pixels;
colours = p_image.colours;
- size = allocation = p_image.size;
+ size = p_image.size;
+ allocation = size + JM_SIZE;
buffer = new uint8_t[allocation];
- memcpy( buffer, p_image.buffer, size );
+ markers = buffer + size;
+ memcpy( buffer, p_image.buffer, allocation );
blend_buffer = 0;
strncpy( text, p_image.text, sizeof(text) );
}
@@ -170,6 +178,7 @@
{
delete[] buffer;
buffer = 0;
+ markers = 0;
allocation = 0;
}
width = height = colours = size = 0;
@@ -184,15 +193,16 @@
pixels = width*height;
colours = p_colours;
size = width*height*colours;
- if ( allocation < size )
+ if ( allocation < size + JM_SIZE )
{
- allocation = size;
+ allocation = size + JM_SIZE;
delete[] buffer;
buffer = new uint8_t[allocation];
- memset( buffer, 0, size );
+ markers = buffer + size;
+ memset( buffer, 0, allocation );
}
}
- memcpy( buffer, new_buffer, size );
+ memcpy( buffer, new_buffer, allocation );
}
void Image::Assign( const Image &image )
@@ -204,15 +214,16 @@
pixels = width*height;
colours = image.colours;
size = width*height*colours;
- if ( allocation < size )
+ if ( allocation < size + JM_SIZE )
{
- allocation = size;
+ allocation = size + JM_SIZE;
delete[] buffer;
buffer = new uint8_t[allocation];
- memset( buffer, 0, size );
+ markers = buffer + size;
+ memset( buffer, 0, allocation );
}
}
- memcpy( buffer, image.buffer, size );
+ memcpy( buffer, image.buffer, allocation );
}
Image *Image::HighlightEdges( Rgb colour, const Box *limits )
@@ -267,13 +278,13 @@
return( false );
}
- if ( statbuf.st_size != size )
+ if ( statbuf.st_size != size + JM_SIZE )
{
Error( "Raw file size mismatch, expected %d bytes, found %ld", size, statbuf.st_size );
return( false );
}
- if ( fread( buffer, size, 1, infile ) < 1 )
+ if ( fread( buffer, size + JM_SIZE, 1, infile ) < 1 )
{
Fatal( "Unable to read from '%s': %s", filename, strerror(errno) );
return( false );
@@ -286,6 +297,7 @@
bool Image::WriteRaw( const char *filename ) const
{
FILE *outfile;
if ( (outfile = fopen( filename, "wb" )) == NULL )
{
@@ -293,7 +305,7 @@
return( false );
}
- if ( fwrite( buffer, size, 1, outfile ) != 1 )
+ if ( fwrite( buffer, size+JM_SIZE, 1, outfile ) != 1 )
{
Error( "Unable to write to '%s': %s", filename, strerror(errno) );
return( false );
@@ -304,6 +316,108 @@
return( true );
}
+void Image::CopyMarkers(jpeg_saved_marker_ptr src)
+{
+
+ unsigned int seek = sizeof(markers_size);
+
+ for (jpeg_saved_marker_ptr mark = src; mark; mark = mark->next) {
+ uint8_t* addr = markers + seek;
+ // Info("Addr %x, seek %d", addr, seek);
+
+ memcpy (addr, &mark->marker, sizeof (UINT8));
+ memcpy (addr + sizeof (UINT8), &mark->data_length, sizeof (unsigned
+ int));
+ memcpy (addr + sizeof (UINT8) + sizeof (unsigned int),
+ mark->data, mark->data_length);
+
+ unsigned int rec_size = sizeof (UINT8) + sizeof (unsigned int)
+ + mark->data_length;
+ seek += rec_size;
+ }
+
+ markers_size = seek - sizeof(markers_size);
+// Info("Marker size: %d", markers_size);
+ memcpy(markers, &markers_size, sizeof(markers_size));
+
+ /*
+ jpeg_saved_marker_ptr dstmark = dst;
+ jpeg_saved_marker_ptr prev = NULL;
+ for(jpeg_saved_marker_ptr srcmark = src; srcmark != NULL; srcmark = srcmark->next)
+ {
+// Info("dstmark: %x, srcmark: %x", srcmark, srcmark);
+ if(!dstmark)
+ {
+ dstmark = new jpeg_marker_struct;
+// Info("dstmark: %x, srcmark: %x", dstmark, srcmark);
+ if(prev)
+ {
+// Info("dstmark: %x, prev: %x", dstmark, prev);
+ prev->next = dstmark;
+ }
+ }
+ dstmark->marker = srcmark->marker;
+ dstmark->data_length = srcmark->data_length;
+ dstmark->original_length = srcmark->original_length;
+// unsigned int data_size = dstmark->data_length*sizeof(JOCTET);
+ dstmark->data = (JOCTET*)malloc(dstmark->data_length);
+ memcpy(dstmark->data, srcmark->data, srcmark->data_length);
+ if(srcmark->next)
+ {
+ prev = dstmark;
+ }
+ else
+ {
+ prev = NULL;
+ }
+
+ dstmark = NULL;
+ }*/
+}
+
+
+void Image::GetMarkers (jpeg_saved_marker_ptr out) const {
+ unsigned int seek = sizeof(markers_size);
+ jpeg_saved_marker_ptr mark = out;
+ jpeg_saved_marker_ptr prev = NULL;
+ int markers_s = 0;
+
+ memcpy (&markers_s, markers, sizeof(markers_size));
+// Info("Marker Size: %d", markers_s);
+ while (seek < markers_s + sizeof(markers_s)) {
+ if (!mark) {
+ mark = new jpeg_marker_struct;
+ }
+
+ if (prev) {
+ prev->next = mark;
+ }
+
+ const uint8_t* addr = markers + seek;
+
+ memcpy (&mark->marker, addr, sizeof (UINT8));
+
+ if (mark->marker > 0) {
+ memcpy (&mark->data_length, addr + sizeof (UINT8),
+ sizeof (unsigned int));
+
+ mark->data = new JOCTET[mark->data_length];
+
+ memcpy (mark->data, addr + sizeof (UINT8) + sizeof (unsigned int),
+ mark->data_length);
+ mark->original_length = mark->data_length;
+ seek += sizeof (UINT8) + sizeof (unsigned int) + mark->data_length;
+ mark->next = NULL;
+ prev = mark;
+ mark = NULL;
+ } else {
+ seek = markers_s + sizeof(markers_s);
+ }
+ }
+
+}
+
+
bool Image::ReadJpeg( const char *filename )
{
struct jpeg_decompress_struct *cinfo = jpg_dcinfo;
@@ -332,8 +446,10 @@
}
jpeg_stdio_src( cinfo, infile );
+ jpeg_save_markers(cinfo, JPEG_COM, 0xffff);
jpeg_read_header( cinfo, TRUE );
+ this->CopyMarkers(cinfo->marker_list);
if ( cinfo->image_width != width || cinfo->image_height != height || cinfo->num_components != colours )
{
@@ -349,11 +465,12 @@
return( false );
}
size = width*height*colours;
- if ( !buffer || allocation < size )
+ if ( !buffer || allocation < size + JM_SIZE)
{
- allocation = size;
+ allocation = size + JM_SIZE;
delete[] buffer;
buffer = new uint8_t[allocation];
+ markers = buffer + size;
}
}
@@ -424,6 +541,15 @@
{
jpeg_write_marker( cinfo, JPEG_COM, (const JOCTET *)text, strlen(text) );
}
+ jpeg_saved_marker_ptr markers_list = new jpeg_marker_struct;
+ this->GetMarkers(markers_list);
+ for (jpeg_saved_marker_ptr marker = markers_list; marker != NULL; marker = marker->next)
+ {
+ //Info("Write marker");
+ jpeg_write_marker(cinfo, marker->marker, marker->data, marker->data_length);
+ }
+
+
JSAMPROW row_pointer; /* pointer to a single row */
int row_stride = cinfo->image_width * cinfo->input_components; /* physical row width in buffer */
@@ -461,7 +587,10 @@
zm_jpeg_mem_src( cinfo, inbuffer, inbuffer_size );
+ jpeg_save_markers(cinfo, JPEG_COM, 0xffff);
+
jpeg_read_header( cinfo, TRUE );
+ this->CopyMarkers(cinfo->marker_list);
if ( cinfo->image_width != width || cinfo->image_height != height || cinfo->num_components != colours )
{
@@ -539,6 +668,13 @@
cinfo->dct_method = JDCT_FASTEST;
jpeg_start_compress( cinfo, TRUE );
+ jpeg_saved_marker_ptr markers_list = new jpeg_marker_struct;
+ this->GetMarkers(markers_list);
+ for (jpeg_saved_marker_ptr marker = markers_list; marker != NULL; marker = marker->next)
+ {
+ //Info("Write marker");
+ jpeg_write_marker(cinfo, marker->marker, marker->data, marker->data_length);
+ }
JSAMPROW row_pointer; /* pointer to a single row */
int row_stride = cinfo->image_width * cinfo->input_components; /* physical row width in buffer */
diff -ruw ZoneMinder-1.25.0/src/zm_image.h zm/src/zm_image.h
--- ZoneMinder-1.25.0/src/zm_image.h 2011-02-15 14:18:42.000000000 +0300
+++ zm/src/zm_image.h 2012-04-13 13:40:05.000000000 +0400
@@ -20,6 +20,8 @@
#ifndef ZM_IMAGE_H
#define ZM_IMAGE_H
+#define JM_SIZE 0xffff
+
#include "zm.h"
extern "C"
{
@@ -89,6 +91,8 @@
int size;
int allocation;
uint8_t *buffer;
+ uint8_t *markers;
+ int markers_size;
bool our_buffer;
char text[1024];
@@ -106,6 +110,8 @@
Image( const Image &p_image );
~Image();
+
+
inline int Width() const { return( width ); }
inline int Height() const { return( height ); }
inline int Pixels() const { return( pixels ); }
@@ -115,6 +121,8 @@
inline uint8_t *Buffer( unsigned int x, unsigned int y= 0 ) const { return( &buffer[colours*((y*width)+x)] ); }
void Empty();
+ void CopyMarkers(jpeg_saved_marker_ptr);
+ void GetMarkers(jpeg_saved_marker_ptr) const;
void Assign( int p_width, int p_height, int p_colours, unsigned char *new_buffer );
void Assign( const Image &image );
@@ -124,11 +132,11 @@
{
Panic( "Attempt to copy different size image buffers, expected %d, got %d", size, image.size );
}
- memcpy( buffer, image.buffer, size );
+ memcpy( buffer, image.buffer, size + JM_SIZE);
}
inline Image &operator=( const unsigned char *new_buffer )
{
- memcpy( buffer, new_buffer, size );
+ memcpy( buffer, new_buffer, size + JM_SIZE);
return( *this );
}
@@ -164,7 +172,7 @@
void Colourise();
void DeColourise();
- void Clear() { memset( buffer, 0, size ); }
+ void Clear() { memset( buffer, 0, size + JM_SIZE ); }
void Fill( Rgb colour, const Box *limits=0 );
void Fill( Rgb colour, int density, const Box *limits=0 );
void Outline( Rgb colour, const Polygon &polygon );
diff -ruw ZoneMinder-1.25.0/src/zm_monitor.cpp zm/src/zm_monitor.cpp
--- ZoneMinder-1.25.0/src/zm_monitor.cpp 2011-03-02 15:23:10.000000000 +0300
+++ zm/src/zm_monitor.cpp 2012-04-13 13:40:05.000000000 +0400
@@ -342,7 +342,7 @@
mem_size = sizeof(SharedData)
+ sizeof(TriggerData)
+ (image_buffer_count*sizeof(struct timeval))
- + (image_buffer_count*camera->ImageSize());
+ + (image_buffer_count*(camera->ImageSize()+JM_SIZE));
Debug( 1, "mem.size=%d", mem_size );
#if ZM_MEM_MAPPED
@@ -444,7 +444,7 @@
for ( int i = 0; i < image_buffer_count; i++ )
{
image_buffer[i].timestamp = &(shared_timestamps[i]);
- image_buffer[i].image = new Image( width, height, camera->Colours(), &(shared_images[i*camera->ImageSize()]) );
+ image_buffer[i].image = new Image( width, height, camera->Colours(), &(shared_images[i*(camera->ImageSize()+JM_SIZE)]) );
}
if ( !n_zones )
{