You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
554 lines
11 KiB
554 lines
11 KiB
/*
|
|
* $Id: pilot-read-notepad.c,v 1.42 2007/02/04 23:06:02 desrod Exp $
|
|
*
|
|
* pilot-read-notepad.c: Translate Palm NotePad database into generic
|
|
* picture format
|
|
*
|
|
* Copyright (c) 2002, Angus Ainslie
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version.
|
|
*
|
|
* This program 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 General
|
|
* Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "pi-source.h"
|
|
#include "pi-notepad.h"
|
|
#include "pi-file.h"
|
|
#include "pi-header.h"
|
|
#include "pi-userland.h"
|
|
|
|
#ifdef HAVE_PNG
|
|
#include "png.h"
|
|
#if (PNG_LIBPNG_VER < 10201)
|
|
#define png_voidp_NULL (png_voidp)NULL
|
|
#define png_error_ptr_NULL (png_error_ptr)NULL
|
|
#endif
|
|
#endif
|
|
|
|
const char *progname;
|
|
|
|
#ifdef HAVE_PNG
|
|
void write_png( FILE *f, struct NotePad *n );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: fmt_date
|
|
*
|
|
* Summary:
|
|
*
|
|
* Parameters: None
|
|
*
|
|
* Return: Nothing
|
|
*
|
|
***********************************************************************/
|
|
static const char *fmt_date ( noteDate_t d )
|
|
{
|
|
|
|
static char buf[24];
|
|
sprintf (buf, "%d-%02d-%02d %02d:%02d:%02d",
|
|
d.year, d.month, d.day, d.hour, d.min, d.sec);
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: write_ppm
|
|
*
|
|
* Summary:
|
|
*
|
|
* Parameters: None
|
|
*
|
|
* Return: Nothing
|
|
*
|
|
***********************************************************************/
|
|
void write_ppm( FILE *f, struct NotePad *n )
|
|
{
|
|
int i,j,k,datapoints = 0;
|
|
unsigned long black = 0;
|
|
unsigned long white = 0xFFFFFFFF;
|
|
|
|
fprintf( f, "P6\n# " );
|
|
|
|
if( n->name != NULL )
|
|
fprintf( f, "%s (created on %s)\n", n->name, fmt_date( n->createDate ));
|
|
else
|
|
fprintf( f, "%s\n", fmt_date( n->createDate ));
|
|
|
|
/* NotePad says that the width is only 152 but it encodes 160 bits */
|
|
/* of data! - AA */
|
|
fprintf( f, "%ld %ld\n255\n",
|
|
n->body.width+8, n->body.height );
|
|
|
|
if( n->body.dataType == NOTEPAD_DATA_BITS )
|
|
for( i=0; i<n->body.dataLen/2; i++ )
|
|
{
|
|
datapoints += n->data[i].repeat;
|
|
|
|
for( j=0; j<n->data[i].repeat; j++ )
|
|
{
|
|
|
|
for( k=0; k<8; k++ )
|
|
{
|
|
if( n->data[i].data & 1<<(7-k) )
|
|
fwrite( &black, 3, 1, f );
|
|
else
|
|
fwrite( &white, 3, 1, f );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
for( i=0; i<n->body.dataLen/2; i++ )
|
|
{
|
|
for( k=0; k<8; k++ )
|
|
{
|
|
if( n->data[i].repeat & 1<<(7-k) )
|
|
fwrite( &black, 3, 1, f );
|
|
else
|
|
fwrite( &white, 3, 1, f );
|
|
}
|
|
for( k=0; k<8; k++ )
|
|
{
|
|
if( n->data[i].data & 1<<(7-k) )
|
|
fwrite( &black, 3, 1, f );
|
|
else
|
|
fwrite( &white, 3, 1, f );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: write_png
|
|
*
|
|
* Summary:
|
|
*
|
|
* Parameters: None
|
|
*
|
|
* Return: Nothing
|
|
*
|
|
***********************************************************************/
|
|
#ifdef HAVE_PNG
|
|
void write_png( FILE *f, struct NotePad *n )
|
|
{
|
|
int i,j,k = 0, width;
|
|
png_structp png_ptr;
|
|
png_infop info_ptr;
|
|
png_bytep row;
|
|
|
|
width = n->body.width + 8;
|
|
|
|
png_ptr = png_create_write_struct
|
|
( PNG_LIBPNG_VER_STRING, png_voidp_NULL,
|
|
png_error_ptr_NULL, png_error_ptr_NULL);
|
|
|
|
if(!png_ptr)
|
|
return;
|
|
|
|
info_ptr = png_create_info_struct(png_ptr);
|
|
if( !info_ptr )
|
|
{
|
|
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
|
return;
|
|
}
|
|
|
|
if( setjmp( png_jmpbuf( png_ptr )))
|
|
{
|
|
png_destroy_write_struct( &png_ptr, &info_ptr );
|
|
fclose( f );
|
|
return;
|
|
}
|
|
|
|
png_init_io( png_ptr, f );
|
|
|
|
png_set_IHDR( png_ptr, info_ptr, width, n->body.height,
|
|
1, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,
|
|
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT );
|
|
|
|
png_write_info( png_ptr, info_ptr );
|
|
|
|
row = (png_bytep)malloc( width/8 * sizeof( png_byte ));
|
|
|
|
if( NULL == row )
|
|
return;
|
|
|
|
if( n->body.dataType == NOTEPAD_DATA_BITS )
|
|
for( i=0, k=0; i<n->body.dataLen/2; i++ )
|
|
for( j=0; j<n->data[i].repeat; j++ )
|
|
{
|
|
row[k] = n->data[i].data ^ 0xFF;
|
|
|
|
if( ++k >= width/8 )
|
|
{
|
|
png_write_row( png_ptr, row );
|
|
k = 0;
|
|
png_write_flush(png_ptr);
|
|
}
|
|
}
|
|
else
|
|
for( i=0, k=0; i<n->body.dataLen/2; i++ )
|
|
{
|
|
row[k] = n->data[i].repeat ^ 0xFF;
|
|
row[k+1] = n->data[i].data ^ 0xFF;
|
|
k += 2;
|
|
if( k >= width/8 )
|
|
{
|
|
png_write_row( png_ptr, row );
|
|
k = 0;
|
|
png_write_flush(png_ptr);
|
|
}
|
|
}
|
|
|
|
png_write_end(png_ptr, info_ptr);
|
|
|
|
free( row );
|
|
|
|
row = NULL;
|
|
|
|
png_destroy_write_struct( &png_ptr, &info_ptr );
|
|
|
|
}
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: write_png_v2
|
|
*
|
|
* Summary:
|
|
*
|
|
* Parameters: None
|
|
*
|
|
* Return: Nothing
|
|
*
|
|
***********************************************************************/
|
|
void write_png_v2( FILE *f, struct NotePad *n )
|
|
{
|
|
if( n->body.dataType != NOTEPAD_DATA_PNG )
|
|
{
|
|
fprintf( stderr, "Bad data Type" );
|
|
return;
|
|
}
|
|
|
|
fwrite( n->data, n->body.dataLen, 1, f );
|
|
fflush( f );
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: print_note_info
|
|
*
|
|
* Summary:
|
|
*
|
|
* Parameters: None
|
|
*
|
|
* Return: Nothing
|
|
*
|
|
***********************************************************************/
|
|
void print_note_info( struct NotePad n, struct NotePadAppInfo nai, int category )
|
|
{
|
|
if( n.flags & NOTEPAD_FLAG_NAME )
|
|
printf( "Name: %s\n", n.name );
|
|
|
|
printf( "Category: %s\n", nai.category.name[category] );
|
|
printf( "Created: %s\n", fmt_date( n.createDate ));
|
|
printf( "Changed: %s\n", fmt_date( n.changeDate ));
|
|
|
|
if( n.flags & NOTEPAD_FLAG_ALARM )
|
|
printf( "Alarm set for: %s\n", fmt_date( n.alarmDate ));
|
|
else
|
|
printf( "Alarm set for: none\n" );
|
|
|
|
printf( "Picture: " );
|
|
|
|
if( n.flags & NOTEPAD_FLAG_BODY )
|
|
printf( "yes\n" );
|
|
else
|
|
printf( "no\n" );
|
|
|
|
printf( "Picture version: %ld\n", n.body.dataType );
|
|
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: output_picture
|
|
*
|
|
* Summary:
|
|
*
|
|
* Parameters: None
|
|
*
|
|
* Return: Nothing
|
|
*
|
|
***********************************************************************/
|
|
void output_picture( int type, struct NotePad n )
|
|
{
|
|
char fname[FILENAME_MAX];
|
|
FILE *f;
|
|
char extension[8];
|
|
static int i = 1;
|
|
|
|
if( n.body.dataType == NOTEPAD_DATA_PNG )
|
|
type = NOTE_OUT_PNG;
|
|
|
|
if( n.flags & NOTEPAD_FLAG_NAME )
|
|
{
|
|
if( type == NOTE_OUT_PNG )
|
|
sprintf( extension, ".png" );
|
|
else if( type == NOTE_OUT_PPM )
|
|
sprintf( extension, ".ppm" );
|
|
|
|
sprintf( fname, "%s", n.name );
|
|
}
|
|
else
|
|
{
|
|
if( type == NOTE_OUT_PNG )
|
|
sprintf( extension, "_np.png" );
|
|
else if( type == NOTE_OUT_PPM )
|
|
sprintf( extension, "_np.ppm" );
|
|
|
|
sprintf( fname, "%4.4d", i++ );
|
|
}
|
|
|
|
if (plu_protect_files( fname, extension, sizeof(fname) ) < 1) {
|
|
goto cleanup;
|
|
}
|
|
|
|
printf ("Generating %s...\n", fname);
|
|
|
|
f = fopen (fname, "wb");
|
|
if( f )
|
|
{
|
|
switch( n.body.dataType )
|
|
{
|
|
case NOTEPAD_DATA_PNG:
|
|
fprintf( stderr, "Notepad data version 2 defaulting to png output.\n" );
|
|
write_png_v2( f, &n );
|
|
break;
|
|
|
|
case NOTEPAD_DATA_BITS:
|
|
case NOTEPAD_DATA_UNCOMPRESSED:
|
|
switch( type )
|
|
{
|
|
case NOTE_OUT_PPM:
|
|
write_ppm( f, &n );
|
|
break;
|
|
|
|
case NOTE_OUT_PNG:
|
|
#ifdef HAVE_PNG
|
|
write_png( f, &n );
|
|
#else
|
|
fprintf( stderr, "read-notepad was built without png support\n" );
|
|
#endif
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
fprintf( stderr, "Picture version is unknown - unable to convert\n" );
|
|
}
|
|
|
|
fclose (f);
|
|
|
|
}
|
|
else {
|
|
fprintf (stderr, "Can't write to %s\n", fname);
|
|
}
|
|
|
|
cleanup:
|
|
free_NotePad( &n );
|
|
}
|
|
|
|
|
|
int main(int argc, const char *argv[])
|
|
{
|
|
int c, /* switch */
|
|
db,
|
|
i,
|
|
sd = -1,
|
|
action = NOTEPAD_ACTION_OUTPUT;
|
|
|
|
int type = NOTE_OUT_PPM;
|
|
|
|
const char
|
|
*typename =
|
|
#ifdef HAVE_PNG
|
|
"png"
|
|
#else
|
|
"ppm"
|
|
#endif
|
|
;
|
|
|
|
struct PilotUser User;
|
|
struct NotePadAppInfo nai;
|
|
pi_buffer_t *buffer;
|
|
|
|
poptContext pc;
|
|
|
|
struct poptOption options[] = {
|
|
USERLAND_RESERVED_OPTIONS
|
|
{"list", 'l', POPT_ARG_VAL, &action, NOTEPAD_ACTION_LIST, "List Notes on device", NULL},
|
|
{"type", 't', POPT_ARG_STRING, &typename, 0, "Specify picture output type, either \"ppm\" or \"png\"", "type"},
|
|
POPT_TABLEEND
|
|
};
|
|
|
|
pc = poptGetContext("read-notepad", argc, argv, options, 0);
|
|
poptSetOtherOptionHelp(pc,"\n\n"
|
|
" Copy or list your NotePad database.\n\n");
|
|
|
|
|
|
if (argc<2) {
|
|
poptPrintUsage(pc,stderr,0);
|
|
return 1;
|
|
}
|
|
while ((c = poptGetNextOpt(pc)) >= 0) {
|
|
fprintf(stderr," ERROR: Unhandled option %d.\n",c);
|
|
return 1;
|
|
}
|
|
if (c < -1) {
|
|
plu_badoption(pc,c);
|
|
}
|
|
|
|
if( !strncmp( "png", typename, 3 ))
|
|
{
|
|
#ifdef HAVE_PNG
|
|
type = NOTE_OUT_PNG;
|
|
#else
|
|
fprintf( stderr, " WARNING: read-notepad was built without png support,\n"
|
|
" using ppm instead.\n" );
|
|
type = NOTE_OUT_PPM;
|
|
#endif
|
|
}
|
|
else if( !strncmp( "ppm", typename, 3 ))
|
|
{
|
|
type = NOTE_OUT_PPM;
|
|
}
|
|
else
|
|
{
|
|
fprintf( stderr, " WARNING: Unknown output type defaulting to ppm\n" );
|
|
type = NOTE_OUT_PPM;
|
|
}
|
|
|
|
sd = plu_connect();
|
|
|
|
if( sd < 0 )
|
|
goto error;
|
|
|
|
if (dlp_ReadUserInfo(sd, &User) < 0)
|
|
goto error_close;
|
|
|
|
/* Open the NotePad database, store access handle in db */
|
|
if( dlp_OpenDB(sd, 0, 0x80 | 0x40, "npadDB", &db ) < 0)
|
|
{
|
|
fprintf(stderr," ERROR: Unable to open NotePadDB on Palm.\n");
|
|
dlp_AddSyncLogEntry(sd, "Unable to open NotePadDB.\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
buffer = pi_buffer_new (0xffff);
|
|
|
|
dlp_ReadAppBlock(sd, db, 0, 0xffff, buffer);
|
|
unpack_NotePadAppInfo( &nai, buffer->data, buffer->used);
|
|
|
|
for (i = 0;; i++)
|
|
{
|
|
int attr,
|
|
category,
|
|
len = 0;
|
|
|
|
struct NotePad n;
|
|
|
|
if( sd )
|
|
{
|
|
len = dlp_ReadRecordByIndex(sd, db, i, buffer, 0,
|
|
&attr, &category);
|
|
|
|
if (len < 0)
|
|
break;
|
|
}
|
|
else
|
|
pi_buffer_clear(buffer);
|
|
|
|
/* Skip deleted records */
|
|
if ((attr & dlpRecAttrDeleted) || (attr & dlpRecAttrArchived))
|
|
continue;
|
|
|
|
unpack_NotePad( &n, buffer->data, buffer->used);
|
|
|
|
switch( action )
|
|
{
|
|
case NOTEPAD_ACTION_LIST:
|
|
print_note_info( n, nai, category );
|
|
printf( "\n" );
|
|
break;
|
|
|
|
case NOTEPAD_ACTION_OUTPUT:
|
|
if (!plu_quiet) {
|
|
print_note_info( n, nai, category );
|
|
}
|
|
output_picture( type, n );
|
|
if (!plu_quiet) {
|
|
printf( "\n" );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
if( sd ) {
|
|
/* Close the database */
|
|
dlp_CloseDB( sd, db );
|
|
dlp_AddSyncLogEntry( sd, "Successfully read NotePad from Palm.\n\n"
|
|
"Thank you for using pilot-link.");
|
|
dlp_EndOfSync( sd, 0 );
|
|
pi_close(sd);
|
|
}
|
|
|
|
pi_buffer_free (buffer);
|
|
|
|
return 0;
|
|
|
|
error_close:
|
|
pi_close(sd);
|
|
|
|
error:
|
|
return -1;
|
|
|
|
}
|
|
|
|
/* vi: set ts=8 sw=4 sts=4 noexpandtab: cin */
|
|
/* ex: set tabstop=4 expandtab: */
|
|
/* Local Variables: */
|
|
/* indent-tabs-mode: t */
|
|
/* c-basic-offset: 8 */
|
|
/* End: */
|
|
|