Source code upload
[framework/connectivity/libgphoto2.git] / camlibs / ax203 / ax203.c
1 /* Appotech ax203 picframe access library
2  *
3  *   Copyright (c) 2010 Hans de Goede <hdegoede@redhat.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation; either version 2.1 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 #include "config.h"
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <_stdint.h>
25 #include <stdlib.h>
26 #include <time.h>
27 #include <fcntl.h>
28 #include <sys/mman.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #ifdef HAVE_GD
32 #include <gd.h>
33 #endif
34
35 #include <gphoto2/gphoto2-result.h>
36 #include "ax203.h"
37 #ifdef HAVE_LIBJPEG
38 #include "jpeg_memsrcdest.h"
39 #endif
40
41 static const struct eeprom_info {
42         const char *name;
43         uint32_t id;
44         int mem_size;
45         int has_4k_sectors;
46 } ax203_eeprom_info[] = {
47         { "AMIC A25L040", 0x37133037,  524288, 1 },
48         { "AMIC A25L080", 0x37143037, 1048576, 1 },
49         { "AMIC A25L40P", 0x1320377f,  524288, 0 },
50         { "AMIC A25L80P", 0x1420377f, 1048576, 0 },
51         { "AMIC A25L16P", 0x1520377f, 2097152, 0 },
52
53         /* Note the ATmel AT26DF041 id:0x0000441f is fsck-ed up. It doesn't
54            support ERASE_64K, (only 4K) and SPI_EEPROM_PP is 0x11 rather then
55            0x02 (0x02 only programs a single byte). */
56         /* I cannot find a datasheet for the ATmel AT26DF081 id:0x0000451f */
57         { "ATmel AT26DF161",  0x0000461f, 2097152, 1 },
58         { "ATmel AT26DF081A", 0x0001451f, 1048576, 1 },
59         { "ATmel AT26DF161A", 0x0001461f, 2097152, 1 },
60         { "ATmel AT25DF081",  0x0002451f, 1048576, 1 },
61         { "ATmel AT25DF161",  0x0002461f, 2097152, 1 },
62
63         { "EON EN25B16", 0x1c15201c, 2097152, 0 },
64         { "EON EN25B32", 0x1c16201c, 4194304, 0 },
65         { "EON EN25F80", 0x1c14311c, 1048576, 1 },
66         { "EON EN25F16", 0x1c15311c, 2097152, 1 },
67
68         { "ESI ES25P80", 0x0014204a, 1048576, 0 },
69         { "ESI ES25P16", 0x0015204a, 2097152, 0 },
70
71         { "ESMT F25L008 (top)",    0x8c14208c, 1048576, 1 },
72         { "ESMT F25L008 (bottom)", 0x8c14218c, 1048576, 1 },
73
74         { "GigaDevice GD25Q40", 0xc81340c8,  524288, 1 },
75         { "GigaDevice GD25Q80", 0xc81440c8, 1048576, 1 },
76         { "GigaDevice GD25Q16", 0xc81540c8, 2097152, 1 },
77
78         { "MXIC MX25L4005A", 0xc21320c2,  524288, 1 },
79         { "MXIC MX25L8005A", 0xc21420c2, 1048576, 1 },
80         { "MXIC MX25L1605A", 0xc21520c2, 2097152, 1 },
81
82         { "PMC Pm25LV010", 0x007e9d7f, 524288, 0 },
83
84         { "Spansion S25FL004A", 0x00120201,  524288, 0 },
85         { "Spansion S25FL008A", 0x00130201, 1048576, 0 },
86         { "Spansion S25FL016A", 0x00140201, 2097152, 0 },
87
88         /* The SST25VF080 and SST25VF016 (id:0xbf8e25bf & 0xbf4125bf) PP
89            instruction can only program a single byte at a time. Thus they
90            are not supported */
91
92         { "ST M25P08", 0x7f142020, 1048576, 0 },
93         { "ST M25P16", 0x7f152020, 2097152, 0 },
94         { "ST M25P32", 0x7f162020, 4194304, 0 },
95         { "ST M25P64", 0x7f172020, 8388608, 0 },
96
97         { "Winbond W25P80", 0x001420ef, 1048576, 0 },
98         { "Winbond W25P16", 0x001520ef, 2097152, 0 },
99
100         { "Winbond W25X40", 0x001330ef,  524288, 1 },
101         { "Winbond W25X80", 0x001430ef, 1048576, 1 },
102         { "Winbond W25X16", 0x001530ef, 2097152, 1 },
103         { "Winbond W25X32", 0x001630ef, 4194304, 1 },
104         { "Winbond W25X64", 0x001730ef, 8388608, 1 },
105
106         { "Winbond W25Q80", 0x001440ef, 1048576, 1 },
107         { "Winbond W25Q16", 0x001540ef, 2097152, 1 },
108         { "Winbond W25Q32", 0x001640ef, 4194304, 1 },
109
110         { }
111 };
112
113 static int
114 ax203_send_cmd(Camera *camera, int to_dev, char *cmd, int cmd_size,
115         char *data, int data_size)
116 {
117         char sense_buffer[32];
118
119         return gp_port_send_scsi_cmd (camera->port, to_dev, cmd, cmd_size,
120                 sense_buffer, sizeof(sense_buffer), data, data_size);
121 }
122
123 static int
124 ax203_send_eeprom_cmd(Camera *camera, int to_dev,
125         char *eeprom_cmd, int eeprom_cmd_size,
126         char *data, int data_size)
127 {
128         char cmd_buffer[16];
129         int i;
130
131         memset (cmd_buffer, 0, sizeof (cmd_buffer));
132         if (to_dev)
133                 cmd_buffer[0] = AX203_TO_DEV;
134         else
135                 cmd_buffer[0] = AX203_FROM_DEV;
136
137         cmd_buffer[5] = AX203_EEPROM_CMD;
138         cmd_buffer[6] = eeprom_cmd_size;
139         cmd_buffer[7] = (data_size >> 16) & 0xff;
140         cmd_buffer[8] = (data_size >> 8) & 0xff;
141         cmd_buffer[9] = (data_size) & 0xff;
142
143         for (i = 0; i < eeprom_cmd_size; i++)
144                 cmd_buffer[10 + i] = eeprom_cmd[i];
145
146         return ax203_send_cmd (camera, to_dev, cmd_buffer, sizeof(cmd_buffer),
147                                data, data_size);
148 }
149
150 static int
151 ax203_get_version(Camera *camera, char *buf)
152 {
153         int ret;
154         char cmd_buffer[16];
155
156         memset (cmd_buffer, 0, sizeof (cmd_buffer));
157
158         cmd_buffer[0] = AX203_FROM_DEV;
159         cmd_buffer[5] = AX203_GET_VERSION;
160         cmd_buffer[6] = 1;
161         cmd_buffer[10] = AX203_GET_VERSION;
162
163         ret = ax203_send_cmd (camera, 0, cmd_buffer, sizeof(cmd_buffer),
164                               buf, 64);
165         buf[63] = 0; /* ensure 0 termination */
166
167         return ret;
168 }
169
170 /* This would be very nice, if only not all devices would answer that they
171    are a 128x128 pixels device */
172 #if 0
173 static int
174 ax203_get_lcd_size(Camera *camera)
175 {
176         char cmd_buffer[16];
177         uint8_t data_buffer[4];
178
179         memset (cmd_buffer, 0, sizeof (cmd_buffer));
180
181         cmd_buffer[0] = AX203_FROM_DEV;
182         cmd_buffer[5] = AX203_GET_LCD_SIZE;
183         cmd_buffer[6] = 0x01;
184         cmd_buffer[10] = AX203_GET_LCD_SIZE;
185
186         CHECK (ax203_send_cmd (camera, 0, cmd_buffer, sizeof (cmd_buffer),
187                                (char *)data_buffer, sizeof (data_buffer)))
188
189         camera->pl->width  = le16atoh (data_buffer);
190         camera->pl->height = le16atoh (data_buffer + 2);
191
192         return GP_OK;
193 }
194 #endif
195
196 static int
197 ax3003_get_frame_id(Camera *camera)
198 {
199         int ret;
200         char cmd_buffer[16];
201         uint8_t id;
202
203         memset (cmd_buffer, 0, sizeof (cmd_buffer));
204
205         cmd_buffer[0] = AX3003_FRAME_CMD;
206         cmd_buffer[1] = AX3003_GET_FRAME_ID;
207
208         ret = ax203_send_cmd (camera, 0, cmd_buffer, sizeof(cmd_buffer),
209                               (char *)&id, 1);
210         if (ret < 0) return ret;
211
212         return id;
213 }
214
215 static int
216 ax3003_get_abfs_start(Camera *camera)
217 {
218         int ret;
219         char cmd_buffer[16];
220         uint8_t buf[2];
221
222         memset (cmd_buffer, 0, sizeof (cmd_buffer));
223
224         cmd_buffer[0] = AX3003_FRAME_CMD;
225         cmd_buffer[1] = AX3003_GET_ABFS_START;
226
227         ret = ax203_send_cmd (camera, 0, cmd_buffer, sizeof(cmd_buffer),
228                               (char *)buf, 2);
229         if (ret < 0) return ret;
230
231         return be16atoh(buf) * 0x100;
232 }
233
234 int
235 ax203_set_time_and_date(Camera *camera, struct tm *t)
236 {
237         char cmd_buffer[16];
238
239         memset (cmd_buffer, 0, sizeof (cmd_buffer));
240         
241         cmd_buffer[0] = AX203_SET_TIME;
242         
243         cmd_buffer[5] = t->tm_year % 100;
244
245         switch (camera->pl->frame_version) {
246         case AX3003_FIRMWARE_3_5_x:
247                 /* Note this is what the windows software does, with the
248                    one AX3003 frame I have this does not do anything */
249                 cmd_buffer[0] = AX3003_FRAME_CMD;
250                 cmd_buffer[1] = AX3003_SET_TIME;
251                 /* fall through */
252         case AX203_FIRMWARE_3_3_x:
253         case AX203_FIRMWARE_3_4_x:
254                 cmd_buffer[6] = t->tm_mon + 1;
255                 cmd_buffer[7] = t->tm_wday;
256                 break;
257         case AX206_FIRMWARE_3_5_x:
258                 cmd_buffer[6] = 19 + t->tm_year / 100;
259                 cmd_buffer[7] = t->tm_mon + 1;
260                 break;
261         }
262         cmd_buffer[8]  = t->tm_mday;
263         cmd_buffer[9]  = t->tm_hour;
264         cmd_buffer[10] = t->tm_min;
265         cmd_buffer[11] = t->tm_sec;
266
267         return ax203_send_cmd (camera, 0, cmd_buffer, sizeof(cmd_buffer),
268                                NULL, 0);
269 }
270
271 static int
272 ax203_eeprom_device_identification(Camera *camera, char *buf)
273 {
274         char cmd = SPI_EEPROM_RDID;
275
276         return ax203_send_eeprom_cmd (camera, 0, &cmd, 1, buf, 4);
277 }
278
279 static int
280 ax203_eeprom_release_from_deep_powerdown(Camera *camera)
281 {
282         char cmd = SPI_EEPROM_RDP;
283
284         return ax203_send_eeprom_cmd (camera, 1, &cmd, 1, NULL, 0);
285 }
286
287 static int
288 ax203_eeprom_read(Camera *camera, int address, char *buf, int buf_size)
289 {
290         char cmd[4];
291     
292         cmd[0] = SPI_EEPROM_READ;
293         cmd[1] = (address >> 16) & 0xff;
294         cmd[2] = (address >> 8) & 0xff;
295         cmd[3] = (address) & 0xff;
296                     
297         return ax203_send_eeprom_cmd (camera, 0, cmd, sizeof(cmd), buf,
298                                       buf_size);
299 }
300
301 static int
302 ax203_eeprom_program_page(Camera *camera, int address, char *buf, int buf_size)
303 {
304         char cmd[4];
305
306         cmd[0] = SPI_EEPROM_PP;
307         cmd[1] = (address >> 16) & 0xff;
308         cmd[2] = (address >> 8) & 0xff;
309         cmd[3] = (address) & 0xff;
310                     
311         return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), buf,
312                                       buf_size);
313 }
314
315 static int
316 ax203_eeprom_write_enable(Camera *camera)
317 {
318         char cmd = SPI_EEPROM_WREN;
319
320         return ax203_send_eeprom_cmd (camera, 1, &cmd, 1, NULL, 0);
321 }
322
323 static int
324 ax203_eeprom_clear_block_protection(Camera *camera)
325 {
326         char cmd[2];
327
328         cmd[0] = SPI_EEPROM_WRSR;
329         cmd[1] = 0;
330
331         return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), NULL, 0);
332 }
333
334 static int
335 ax203_eeprom_erase_4k_sector(Camera *camera, int address)
336 {
337         char cmd[4];
338
339         cmd[0] = SPI_EEPROM_ERASE_4K;
340         cmd[1] = (address >> 16) & 0xff;
341         cmd[2] = (address >> 8) & 0xff;
342         cmd[3] = (address) & 0xff;
343                     
344         return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), NULL, 0);
345 }
346
347 static int
348 ax203_eeprom_erase_64k_sector(Camera *camera, int address)
349 {
350         char cmd[4];
351
352         cmd[0] = SPI_EEPROM_ERASE_64K;
353         cmd[1] = (address >> 16) & 0xff;
354         cmd[2] = (address >> 8) & 0xff;
355         cmd[3] = (address) & 0xff;
356                     
357         return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), NULL, 0);
358 }
359
360 static int
361 ax203_eeprom_wait_ready(Camera *camera)
362 {
363         char cmd = SPI_EEPROM_RDSR; /* Read status */
364         char buf[64];
365         int count = 0;
366
367         switch (camera->pl->frame_version) {
368         case AX203_FIRMWARE_3_3_x:
369         case AX203_FIRMWARE_3_4_x:
370         case AX206_FIRMWARE_3_5_x:
371                 /* Do as windows does, read the status word 64 times,
372                    then check */
373                 count = 64;
374                 break;
375         case AX3003_FIRMWARE_3_5_x:
376                 /* On the ax3003 contineously reading the status word
377                    does not work. */
378                 count = 1;
379                 break;
380         }
381
382         while (1) {
383                 CHECK (ax203_send_eeprom_cmd (camera, 0, &cmd, 1, buf, count))
384                 /* We only need to check the last read */
385                 if (!(buf[count - 1] & 0x01)) /* Check write in progress bit */
386                         break; /* No write in progress, done waiting */
387         }
388         return GP_OK;
389 }
390
391 static int
392 ax203_read_sector(Camera *camera, int sector, char *buf)
393 {
394         int ret;
395         if (camera->pl->mem_dump) {
396                 ret = fseek (camera->pl->mem_dump,
397                              sector * SPI_EEPROM_SECTOR_SIZE, SEEK_SET);
398                 if (ret) {
399                         gp_log (GP_LOG_ERROR, "ax203",
400                                 "seeking in memdump: %s", strerror(errno));
401                         return GP_ERROR_IO_READ;
402                 }
403                 ret = fread (buf, 1, SPI_EEPROM_SECTOR_SIZE,
404                              camera->pl->mem_dump);
405                 if (ret != SPI_EEPROM_SECTOR_SIZE) {
406                         if (ret < 0)
407                                 gp_log (GP_LOG_ERROR, "ax203",
408                                         "reading memdump: %s",
409                                         strerror(errno));
410                         else
411                                 gp_log (GP_LOG_ERROR, "ax203",
412                                         "short read reading from memdump");
413                         return GP_ERROR_IO_READ;
414                 }
415         } else {
416                 CHECK (ax203_eeprom_read (camera,
417                                           sector * SPI_EEPROM_SECTOR_SIZE,
418                                           buf, SPI_EEPROM_SECTOR_SIZE))
419         }
420         return GP_OK;
421 }
422
423 static int
424 ax203_write_sector(Camera *camera, int sector, char *buf)
425 {
426         int ret;
427         if (camera->pl->mem_dump) {
428                 ret = fseek (camera->pl->mem_dump,
429                              sector * SPI_EEPROM_SECTOR_SIZE, SEEK_SET);
430                 if (ret) {
431                         gp_log (GP_LOG_ERROR, "ax203",
432                                 "seeking in memdump: %s", strerror(errno));
433                         return GP_ERROR_IO_WRITE;
434                 }
435                 ret = fwrite (buf, 1, SPI_EEPROM_SECTOR_SIZE,
436                               camera->pl->mem_dump);
437                 if (ret != SPI_EEPROM_SECTOR_SIZE) {
438                         gp_log (GP_LOG_ERROR, "ax203",
439                                 "writing memdump: %s", strerror(errno));
440                         return GP_ERROR_IO_WRITE;
441                 }
442         } else {
443                 int i, base = sector * SPI_EEPROM_SECTOR_SIZE;
444
445                 for (i = 0; i < SPI_EEPROM_SECTOR_SIZE; i += 256) {
446                         CHECK (ax203_eeprom_write_enable (camera))
447                         CHECK (ax203_eeprom_program_page (camera, base + i,
448                                                           buf + i, 256))
449                         CHECK (ax203_eeprom_wait_ready (camera))
450                 }
451         }
452         return GP_OK;
453 }
454
455 static int
456 ax203_erase4k_sector(Camera *camera, int sector)
457 {
458         if (camera->pl->mem_dump)
459                 return GP_OK;
460
461         CHECK (ax203_eeprom_write_enable (camera))
462         CHECK (ax203_eeprom_erase_4k_sector (camera,
463                                              sector * SPI_EEPROM_SECTOR_SIZE))
464         CHECK (ax203_eeprom_wait_ready (camera))
465
466         return GP_OK;
467 }
468
469 static int
470 ax203_erase64k_sector(Camera *camera, int sector)
471 {
472         if (camera->pl->mem_dump)
473                 return GP_OK;
474
475         CHECK (ax203_eeprom_write_enable (camera))
476         CHECK (ax203_eeprom_erase_64k_sector (camera,
477                                              sector * SPI_EEPROM_SECTOR_SIZE))
478         CHECK (ax203_eeprom_wait_ready (camera))
479
480         return GP_OK;
481 }
482
483 static int
484 ax203_check_sector_present(Camera *camera, int sector)
485 {
486         int ret;
487
488         if ((sector + 1) * SPI_EEPROM_SECTOR_SIZE > camera->pl->mem_size) {
489                 gp_log (GP_LOG_ERROR, "ax203", "access beyond end of memory");
490                 return GP_ERROR_CORRUPTED_DATA;
491         }
492
493         if (camera->pl->sector_is_present[sector])
494                 return GP_OK;
495
496         ret = ax203_read_sector(camera, sector, camera->pl->mem +
497                                 sector * SPI_EEPROM_SECTOR_SIZE);
498         if (ret == 0)
499                 camera->pl->sector_is_present[sector] = 1;
500
501         return ret;
502 }
503
504 static int
505 ax203_read_mem(Camera *camera, int offset,
506         void *buf, int len)
507 {
508         int to_copy, sector = offset / SPI_EEPROM_SECTOR_SIZE;
509
510         while (len) {
511                 CHECK (ax203_check_sector_present (camera, sector))
512
513                 to_copy = SPI_EEPROM_SECTOR_SIZE -
514                           (offset % SPI_EEPROM_SECTOR_SIZE);
515                 if (to_copy > len)
516                         to_copy = len;
517
518                 memcpy(buf, camera->pl->mem + offset, to_copy);
519                 buf += to_copy;
520                 len -= to_copy;
521                 offset += to_copy;
522                 sector++;
523         }
524         return GP_OK;
525 }
526
527 static int
528 ax203_write_mem(Camera *camera, int offset,
529         void *buf, int len)
530 {
531         int to_copy, sector = offset / SPI_EEPROM_SECTOR_SIZE;
532
533         while (len) {
534                 CHECK (ax203_check_sector_present (camera, sector))
535
536                 to_copy = SPI_EEPROM_SECTOR_SIZE -
537                           (offset % SPI_EEPROM_SECTOR_SIZE);
538                 if (to_copy > len)
539                         to_copy = len;
540
541                 memcpy(camera->pl->mem + offset, buf, to_copy);
542                 camera->pl->sector_dirty[sector] = 1;
543
544                 buf += to_copy;
545                 len -= to_copy;
546                 offset += to_copy;
547                 sector++;
548         }
549         return GP_OK;
550 }
551
552 /* This function reads the parameter block from the eeprom and:
553    1) checks some hopefully constant bytes to make sure it is not reading
554       garbage
555    2) Gets the lcd size from the paramter block (ax203_get_lcd_size seems
556       to result in all frames being detected as being 128x128 pixels).
557    3) Determines the compression type for v3.4.x frames
558    4) Determines the start of the ABFS
559 */
560 static int ax203_read_parameter_block(Camera *camera)
561 {
562         uint8_t buf[32], expect[32];
563         int i, param_offset = 0, resolution_offset = 0;
564         int compression_offset = -1, abfs_start_offset = 0, expect_size = 0;
565         const int valid_resolutions[][2] = {
566                 {  96,  64 },
567                 { 120, 160 },
568                 { 128, 128 },
569                 { 132, 132 },
570                 { 128, 160 },
571                 { 160, 120 },
572                 { 160, 128 },
573                 { 240, 320 },
574                 { 320, 240 },
575                 { }
576         };
577         const uint8_t expect_33x[] = {
578                 0x13, 0x15, 0, 0, 0x02, 0x01, 0x02, 0x01,
579                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
580         const uint8_t expect_34x[] = {
581                 0x13, 0x15, 0, 0, 0, 0, 0, 0x01,
582                 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
583         const uint8_t expect_35x[] = {
584                 0x00, 0x00, 0, 0, 0, 0, 0, 0xd8 };
585
586         switch (camera->pl->frame_version) {
587         case AX203_FIRMWARE_3_3_x:
588                 param_offset = 0x50;
589                 resolution_offset  = 2;
590                 abfs_start_offset  = 16;
591                 memcpy (expect, expect_33x, sizeof(expect_33x));
592                 expect_size = sizeof(expect_33x);
593                 /* Byte 4 of the parameter block probably is the compression
594                    type like with v3.4.x, but this needs confirmation. */
595                 camera->pl->compression_version = AX203_COMPRESSION_YUV;
596                 break;
597         case AX203_FIRMWARE_3_4_x:
598                 param_offset = 0x50;
599                 resolution_offset  = 2;
600                 compression_offset = 6;
601                 abfs_start_offset  = 16;
602                 memcpy (expect, expect_34x, sizeof(expect_34x));
603                 expect_size = sizeof(expect_34x);
604                 break;
605         case AX206_FIRMWARE_3_5_x:
606                 param_offset = 0x20;
607                 abfs_start_offset  = 2;
608                 resolution_offset  = 3;
609                 memcpy (expect, expect_35x, sizeof(expect_35x));
610                 expect_size = sizeof(expect_35x);
611                 /* ax206 + 3.5.x firmware has a fixed compression type */
612                 camera->pl->compression_version = AX206_COMPRESSION_JPEG;
613                 break;
614         case AX3003_FIRMWARE_3_5_x:
615                 i = ax3003_get_frame_id (camera);
616                 if (i < 0) return i;
617                 switch (i) {
618                 case 0:
619                         camera->pl->width  = 320;
620                         camera->pl->height = 240;
621                         break;
622                 default:
623                         gp_log (GP_LOG_ERROR, "ax203",
624                                 "unknown ax3003 frame id: %d", i);
625                         return GP_ERROR_MODEL_NOT_FOUND;
626                 }
627
628                 i = ax3003_get_abfs_start (camera);
629                 if (i < 0) return i;
630                 camera->pl->fs_start = i;
631
632                 camera->pl->compression_version = AX3003_COMPRESSION_JPEG;
633
634                 goto verify_parameters;
635         }
636
637         CHECK (ax203_read_mem (camera, param_offset, buf, sizeof(buf)))
638
639         switch (camera->pl->frame_version) {
640         case AX203_FIRMWARE_3_3_x:
641                 /* 1 byte width / height */
642                 camera->pl->width  = buf[resolution_offset    ];
643                 camera->pl->height = buf[resolution_offset + 1];
644                 expect[resolution_offset    ] = camera->pl->width;
645                 expect[resolution_offset + 1] = camera->pl->height;
646                 break;
647         case AX203_FIRMWARE_3_4_x:
648         case AX206_FIRMWARE_3_5_x:
649                 /* 2 byte little endian width / height */
650                 camera->pl->width  = le16atoh (buf + resolution_offset);
651                 camera->pl->height = le16atoh (buf + resolution_offset + 2);
652                 htole16a(expect + resolution_offset    , camera->pl->width);
653                 htole16a(expect + resolution_offset + 2, camera->pl->height);
654                 break;
655         case AX3003_FIRMWARE_3_5_x:
656                 /* Never reached, here to silence a compiler warning */
657                 break;
658         }
659
660         if (compression_offset != -1) {
661                 i = buf[compression_offset];
662                 switch (i) {
663                 case 2:
664                         camera->pl->compression_version =
665                                 AX203_COMPRESSION_YUV;
666                         break;
667                 case 3:
668                         camera->pl->compression_version =
669                                 AX203_COMPRESSION_YUV_DELTA;
670                         break;
671                 default:
672                         gp_log (GP_LOG_ERROR, "ax203",
673                                 "unknown compression version: %d", i);
674                         return GP_ERROR_MODEL_NOT_FOUND;
675                 }
676                 expect[compression_offset] = i;
677         }
678
679         i = buf[abfs_start_offset];
680         camera->pl->fs_start = i * 0x10000;
681         expect[abfs_start_offset] = i;
682
683         if (memcmp (buf, expect, expect_size)) {
684                 gp_log (GP_LOG_ERROR, "ax203",
685                         "unexpected contents of parameter block");
686                 return GP_ERROR_MODEL_NOT_FOUND;
687         }
688
689 verify_parameters:
690         for (i = 0; valid_resolutions[i][0]; i++)
691                 if (valid_resolutions[i][0] == camera->pl->width &&
692                     valid_resolutions[i][1] == camera->pl->height)
693                         break;
694
695         if (!valid_resolutions[i][0]) {
696                 gp_log (GP_LOG_ERROR, "ax203", "unknown resolution: %dx%d",
697                         camera->pl->width, camera->pl->height);
698                 return GP_ERROR_MODEL_NOT_FOUND;
699         }
700
701         CHECK (ax203_read_mem (camera, camera->pl->fs_start, buf, 4))
702         if (memcmp (buf, AX203_ABFS_MAGIC, 4)) {
703                 gp_log (GP_LOG_ERROR, "ax203", "ABFS magic not found at: %x",
704                         camera->pl->fs_start);
705                 return GP_ERROR_MODEL_NOT_FOUND;
706         }
707
708         GP_DEBUG ("lcd size %dx%d, compression ver: %d, fs-start: %x",
709                   camera->pl->width, camera->pl->height,
710                   camera->pl->compression_version, camera->pl->fs_start);
711
712         return GP_OK;
713 }
714
715 static int ax203_check_file_index(Camera *camera, int idx)
716 {
717         int count;
718
719         if (idx < 0) {
720                 gp_log (GP_LOG_ERROR, "ax203",
721                         "file index < 0");
722                 return GP_ERROR_BAD_PARAMETERS;
723         }
724
725         count = ax203_read_filecount (camera);
726         if (count < 0) return count;
727
728         if (idx >= count) {
729                 gp_log (GP_LOG_ERROR, "ax203",
730                         "file index beyond end of ABFS");
731                 return GP_ERROR_BAD_PARAMETERS;
732         }
733
734         return GP_OK;
735 }
736
737 int
738 ax203_filesize(Camera *camera)
739 {
740         switch (camera->pl->compression_version) {
741         case AX203_COMPRESSION_YUV:
742                 return camera->pl->width * camera->pl->height;
743         case AX203_COMPRESSION_YUV_DELTA:
744                 return camera->pl->width * camera->pl->height * 3 / 4;
745         case AX206_COMPRESSION_JPEG:
746         case AX3003_COMPRESSION_JPEG:
747                 /* Variable size */
748                 return 0;
749         }
750         /* Never reached */
751         return GP_ERROR_NOT_SUPPORTED;  
752 }
753
754 static int
755 ax203_max_filecount(Camera *camera)
756 {
757         switch (camera->pl->frame_version) {
758         case AX203_FIRMWARE_3_3_x:
759         case AX203_FIRMWARE_3_4_x:
760                 return (AX203_ABFS_SIZE - AX203_ABFS_FILE_OFFSET (0)) / 2;
761         case AX206_FIRMWARE_3_5_x:
762                 return (AX203_ABFS_SIZE - AX206_ABFS_FILE_OFFSET (0)) /
763                         sizeof(struct ax206_v3_5_x_raw_fileinfo);
764         case AX3003_FIRMWARE_3_5_x:
765                 return (AX203_ABFS_SIZE - AX3003_ABFS_FILE_OFFSET (0)) /
766                         sizeof(struct ax3003_v3_5_x_raw_fileinfo);
767         }
768         /* Never reached */
769         return GP_ERROR_NOT_SUPPORTED;  
770 }
771
772 static int
773 ax203_read_v3_3_x_v3_4_x_filecount(Camera *camera)
774 {
775         /* The v3.3.x and v3.4.x firmware ABFS keeps a single byte file count
776            at (camera->pl->fs_start + AX203_ABFS_COUNT_OFFSET) However the
777            frame does not seem to care about this.
778            So always return the maximum number of entries the ABFS can contain
779            (and rely on fileinfo.present to figure out how many files there
780             actually are). */
781         return ax203_max_filecount (camera);
782 }
783
784 static int
785 ax203_write_v3_3_x_v3_4_x_filecount(Camera *camera, int count)
786 {
787         uint8_t c = count;
788
789         /* Despite the frame not caring, we do write the filecount just
790            like windows does. */
791         CHECK (ax203_write_mem (camera,
792                                 camera->pl->fs_start + AX203_ABFS_COUNT_OFFSET,
793                                 &c, 1))
794         return GP_OK;
795 }
796
797 static int
798 ax203_read_v3_5_x_filecount(Camera *camera)
799 {
800         /* The v3.5.x firmware ABFS does not contain a separate file count,
801            so always return the maximum number of entries it can contain
802            (and rely on fileinfo.present to figure out how many files there
803             actually are). */
804         return ax203_max_filecount (camera);
805 }
806
807 static int
808 ax203_write_v3_5_x_filecount(Camera *camera, int count)
809 {
810         /* This is a no-op as the v3.5.x firmware ABFS does not contain a
811            separate file count */
812         return GP_OK;
813 }
814
815 static
816 int ax203_read_v3_3_x_v3_4_x_fileinfo(Camera *camera, int idx,
817         struct ax203_fileinfo *fileinfo)
818 {
819         uint8_t buf[2];
820
821         CHECK (ax203_read_mem (camera,
822                                camera->pl->fs_start +
823                                         AX203_ABFS_FILE_OFFSET (idx),
824                                buf, 2))
825
826         fileinfo->address = le16atoh (buf) << 8;
827         fileinfo->size    = ax203_filesize (camera);
828         fileinfo->present = fileinfo->address? 1 : 0;
829
830         return GP_OK;
831 }
832
833 static
834 int ax203_write_v3_3_x_v3_4_x_fileinfo(Camera *camera, int idx,
835         struct ax203_fileinfo *fileinfo)
836 {
837         uint8_t buf[2];
838
839         if (fileinfo->address & 0xff) {
840                 gp_log (GP_LOG_ERROR, "ax203", "LSB of address is not 0");
841                 return GP_ERROR_BAD_PARAMETERS;
842         }
843
844         if (!fileinfo->present)
845                 fileinfo->address = 0;
846
847         htole16a(buf, fileinfo->address >> 8);
848         CHECK (ax203_write_mem (camera,
849                                 camera->pl->fs_start +
850                                         AX203_ABFS_FILE_OFFSET (idx),
851                                 buf, 2))
852
853         return GP_OK;
854 }
855
856 static
857 int ax206_read_v3_5_x_fileinfo(Camera *camera, int idx,
858         struct ax203_fileinfo *fileinfo)
859 {
860         struct ax206_v3_5_x_raw_fileinfo raw;
861
862         CHECK (ax203_read_mem (camera,
863                                camera->pl->fs_start +
864                                         AX206_ABFS_FILE_OFFSET (idx),
865                                &raw, sizeof(raw)))
866
867         fileinfo->present = raw.present == 0x01;
868         fileinfo->address = le32toh (raw.address);
869         fileinfo->size    = le16toh (raw.size);
870
871         return GP_OK;   
872 }
873
874 static
875 int ax206_write_v3_5_x_fileinfo(Camera *camera, int idx,
876         struct ax203_fileinfo *fileinfo)
877 {
878         struct ax206_v3_5_x_raw_fileinfo raw;
879
880         raw.present = fileinfo->present;
881         raw.address = htole32(fileinfo->address);
882         raw.size    = htole16(fileinfo->size);
883
884         CHECK (ax203_write_mem (camera,
885                                 camera->pl->fs_start +
886                                         AX206_ABFS_FILE_OFFSET (idx),
887                                 &raw, sizeof(raw)))
888
889         return GP_OK;
890 }
891
892 static
893 int ax3003_read_v3_5_x_fileinfo(Camera *camera, int idx,
894         struct ax203_fileinfo *fileinfo)
895 {
896         struct ax3003_v3_5_x_raw_fileinfo raw;
897
898         CHECK (ax203_read_mem (camera,
899                                camera->pl->fs_start +
900                                         AX3003_ABFS_FILE_OFFSET (idx),
901                                &raw, sizeof(raw)))
902
903         fileinfo->present = raw.address && raw.size;
904         fileinfo->address = be16toh (raw.address) * 0x100;
905         fileinfo->size    = be16toh (raw.size) * 0x100;
906
907         return GP_OK;
908 }
909
910 static
911 int ax3003_write_v3_5_x_fileinfo(Camera *camera, int idx,
912         struct ax203_fileinfo *fileinfo)
913 {
914         struct ax3003_v3_5_x_raw_fileinfo raw;
915
916         if (fileinfo->address & 0xff) {
917                 gp_log (GP_LOG_ERROR, "ax203", "LSB of address is not 0");
918                 return GP_ERROR_BAD_PARAMETERS;
919         }
920
921         if (fileinfo->size & 0xff) {
922                 gp_log (GP_LOG_ERROR, "ax203", "LSB of size is not 0");
923                 return GP_ERROR_BAD_PARAMETERS;
924         }
925
926         if (fileinfo->present) {
927                 raw.address = htobe16(fileinfo->address / 0x100);
928                 raw.size    = htobe16(fileinfo->size / 0x100);
929         } else {
930                 raw.address = 0;
931                 raw.size    = 0;
932         }
933
934         CHECK (ax203_write_mem (camera,
935                                 camera->pl->fs_start +
936                                         AX3003_ABFS_FILE_OFFSET (idx),
937                                 &raw, sizeof(raw)))
938
939         return GP_OK;
940 }
941
942 /***************** Begin "public" functions *****************/
943
944 int
945 ax203_read_filecount(Camera *camera)
946 {
947         switch (camera->pl->frame_version) {
948         case AX203_FIRMWARE_3_3_x:
949         case AX203_FIRMWARE_3_4_x:
950                 return ax203_read_v3_3_x_v3_4_x_filecount (camera);
951         case AX206_FIRMWARE_3_5_x:
952         case AX3003_FIRMWARE_3_5_x:
953                 return ax203_read_v3_5_x_filecount (camera);;
954         }
955         /* Never reached */
956         return GP_ERROR_NOT_SUPPORTED;
957 }
958
959 static int
960 ax203_update_filecount(Camera *camera)
961 {
962         int i, max, count = 0;
963
964         /* "Calculate" the real file count */
965         max = ax203_max_filecount (camera);
966         for (i = 0; i < max; i++) {
967                 if (ax203_file_present (camera, i))
968                         count = i + 1;
969         }
970
971         switch (camera->pl->frame_version) {
972         case AX203_FIRMWARE_3_3_x:
973         case AX203_FIRMWARE_3_4_x:
974                 return ax203_write_v3_3_x_v3_4_x_filecount (camera, count);
975         case AX206_FIRMWARE_3_5_x:
976         case AX3003_FIRMWARE_3_5_x:
977                 return ax203_write_v3_5_x_filecount (camera, count);
978         }
979         /* Never reached */
980         return GP_ERROR_NOT_SUPPORTED;
981 }
982
983 static
984 int ax203_read_fileinfo(Camera *camera, int idx,
985         struct ax203_fileinfo *fileinfo)
986 {
987         CHECK (ax203_check_file_index (camera, idx))
988
989         switch (camera->pl->frame_version) {
990         case AX203_FIRMWARE_3_3_x:
991         case AX203_FIRMWARE_3_4_x:
992                 return ax203_read_v3_3_x_v3_4_x_fileinfo (camera, idx,
993                                                           fileinfo);
994         case AX206_FIRMWARE_3_5_x:
995                 return ax206_read_v3_5_x_fileinfo (camera, idx, fileinfo);
996         case AX3003_FIRMWARE_3_5_x:
997                 return ax3003_read_v3_5_x_fileinfo (camera, idx, fileinfo);
998         }
999         /* Never reached */
1000         return GP_ERROR_NOT_SUPPORTED;  
1001 }
1002
1003 static
1004 int ax203_write_fileinfo(Camera *camera, int idx,
1005         struct ax203_fileinfo *fileinfo)
1006 {
1007         switch (camera->pl->frame_version) {
1008         case AX203_FIRMWARE_3_3_x:
1009         case AX203_FIRMWARE_3_4_x:
1010                 return ax203_write_v3_3_x_v3_4_x_fileinfo (camera, idx,
1011                                                            fileinfo);
1012         case AX206_FIRMWARE_3_5_x:
1013                 return ax206_write_v3_5_x_fileinfo (camera, idx, fileinfo);
1014         case AX3003_FIRMWARE_3_5_x:
1015                 return ax3003_write_v3_5_x_fileinfo (camera, idx, fileinfo);
1016         }
1017         /* Never reached */
1018         return GP_ERROR_NOT_SUPPORTED;  
1019 }
1020
1021 int
1022 ax203_file_present(Camera *camera, int idx)
1023 {
1024         struct ax203_fileinfo fileinfo;
1025         
1026         CHECK (ax203_read_fileinfo (camera, idx, &fileinfo))
1027
1028         return fileinfo.present;
1029 }
1030
1031 static int
1032 ax203_decode_image(Camera *camera, char *src, int src_size, int **dest)
1033 {
1034 #ifdef HAVE_GD
1035         int ret;
1036         unsigned int x, y, width, height, row_skip = 0;
1037         unsigned char *components[3];
1038 #ifdef HAVE_LIBJPEG
1039         struct jpeg_decompress_struct dinfo;
1040         struct jpeg_error_mgr jderr;
1041         JSAMPLE row[camera->pl->width * 3];
1042         JSAMPROW row_pointer[1] = { row };
1043 #endif
1044
1045         switch (camera->pl->compression_version) {
1046         case AX203_COMPRESSION_YUV:
1047                 ax203_decode_yuv (src, dest, camera->pl->width,
1048                                   camera->pl->height);
1049                 return GP_OK;
1050         case AX203_COMPRESSION_YUV_DELTA:
1051                 ax203_decode_yuv_delta (src, dest, camera->pl->width,
1052                                         camera->pl->height);
1053                 return GP_OK;
1054         case AX206_COMPRESSION_JPEG:
1055                 /* Note this uses a modified tinyjpeg which was modified to
1056                    handle the AX206' custom JPEG format (the AX3003 uses
1057                    normal JPEG compression). */
1058                 if (!camera->pl->jdec) {
1059                         camera->pl->jdec = tinyjpeg_init ();
1060                         if (!camera->pl->jdec)
1061                                 return GP_ERROR_NO_MEMORY;
1062                 }
1063                 
1064                 /* Hack for width / heights which are not a multiple of 16 */
1065                 if (camera->pl->width % 16 || camera->pl->height % 16) {
1066                         width  = (camera->pl->width  + 15) & ~15;
1067                         height = (camera->pl->height + 15) & ~15;
1068                         htobe16a(src,     width);
1069                         htobe16a(src + 2, height);
1070                         row_skip = (width - camera->pl->width) * 3;
1071                 }
1072                 ret = tinyjpeg_parse_header (camera->pl->jdec,
1073                                              (unsigned char *)src, src_size);
1074                 if (ret) {
1075                         gp_log (GP_LOG_ERROR, "ax203",
1076                                 "Error parsing header: %s",
1077                                 tinyjpeg_get_errorstring (camera->pl->jdec));
1078                         return GP_ERROR_CORRUPTED_DATA;
1079                 }
1080                 if (!row_skip) {
1081                         tinyjpeg_get_size (camera->pl->jdec, &width, &height);
1082                         if ((int)width  != camera->pl->width ||
1083                             (int)height != camera->pl->height) {
1084                                 gp_log (GP_LOG_ERROR, "ax203",
1085                                         "Hdr dimensions %ux%u don't match lcd %dx%d",
1086                                         width, height,
1087                                         camera->pl->width, camera->pl->height);
1088                                 return GP_ERROR_CORRUPTED_DATA;
1089                         }
1090                 }
1091                 ret = tinyjpeg_decode (camera->pl->jdec);
1092                 if (ret) {
1093                         gp_log (GP_LOG_ERROR, "ax203",
1094                                 "Error decoding JPEG data: %s",
1095                                 tinyjpeg_get_errorstring (camera->pl->jdec));
1096                         return GP_ERROR_CORRUPTED_DATA;
1097                 }
1098                 tinyjpeg_get_components (camera->pl->jdec, components);
1099                 for (y = 0; y < camera->pl->height; y++) {
1100                         for (x = 0; x < camera->pl->width; x++) {
1101                                 dest[y][x] = gdTrueColor (components[0][0],
1102                                                           components[0][1],
1103                                                           components[0][2]);
1104                                 components[0] += 3;
1105                         }
1106                         components[0] += row_skip;
1107                 }
1108                 return GP_OK;
1109         case AX3003_COMPRESSION_JPEG:
1110 #ifdef HAVE_LIBJPEG
1111                 dinfo.err = jpeg_std_error (&jderr);
1112                 jpeg_create_decompress (&dinfo);
1113                 jpeg_mem_src (&dinfo, (unsigned char *)src, src_size);
1114                 jpeg_read_header (&dinfo, TRUE);
1115                 jpeg_start_decompress (&dinfo);
1116                 if (dinfo.output_width  != camera->pl->width ||
1117                     dinfo.output_height != camera->pl->height ||
1118                     dinfo.output_components != 3 ||
1119                     dinfo.out_color_space != JCS_RGB) {
1120                         gp_log (GP_LOG_ERROR, "ax203",
1121                                 "Wrong JPEG header parameters: %dx%d, "
1122                                 "%d components, colorspace: %d",
1123                                 dinfo.output_width, dinfo.output_height,
1124                                 dinfo.output_components,
1125                                 dinfo.out_color_space);
1126                         return GP_ERROR_CORRUPTED_DATA;
1127                 }
1128
1129                 for (y = 0; y < dinfo.output_height; y++) {
1130                         jpeg_read_scanlines (&dinfo, row_pointer, 1);
1131                         for (x = 0; x < dinfo.output_width; x++) {
1132                                 dest[y][x] = gdTrueColor (row[x * 3 + 0],
1133                                                           row[x * 3 + 1],
1134                                                           row[x * 3 + 2]);
1135                         }
1136                 }
1137                 jpeg_finish_decompress (&dinfo);
1138                 jpeg_destroy_decompress (&dinfo);
1139                 return GP_OK;
1140 #else
1141                 gp_log(GP_LOG_ERROR,"ax203", "jpeg decompression not supported - no libjpeg during build");
1142                 return GP_ERROR_NOT_SUPPORTED;
1143 #endif
1144                 break;
1145         }
1146 #endif
1147         gp_log(GP_LOG_ERROR,"ax203", "GD decompression not supported - no libGD present during build");
1148         /* Never reached */
1149         return GP_ERROR_NOT_SUPPORTED;
1150 }
1151
1152 /* Returns the number of bytes of dest used or a negative error code */
1153 static int
1154 ax203_encode_image(Camera *camera, int **src, char *dest, int dest_size)
1155 {
1156 #ifdef HAVE_GD
1157         int size = ax203_filesize (camera);
1158 #ifdef HAVE_LIBJPEG
1159         int x, y;
1160         struct jpeg_compress_struct cinfo;
1161         struct jpeg_error_mgr jcerr;
1162         JOCTET *jpeg_dest = NULL;
1163         unsigned long jpeg_size = 0;
1164         JSAMPLE row[camera->pl->width * 3];
1165         JSAMPROW row_pointer[1] = { row };
1166 #endif
1167
1168         if (dest_size < size)
1169                 return GP_ERROR_FIXED_LIMIT_EXCEEDED;
1170
1171         switch (camera->pl->compression_version) {
1172         case AX203_COMPRESSION_YUV:
1173                 ax203_encode_yuv (src, dest, camera->pl->width,
1174                                   camera->pl->height);
1175                 return size;
1176         case AX203_COMPRESSION_YUV_DELTA:
1177                 ax203_encode_yuv_delta (src, dest, camera->pl->width,
1178                                         camera->pl->height);
1179                 return size;
1180         case AX206_COMPRESSION_JPEG:
1181                 return ax206_compress_jpeg (camera, src,
1182                                             (uint8_t *)dest, dest_size,
1183                                             camera->pl->width,
1184                                             camera->pl->height);
1185         case AX3003_COMPRESSION_JPEG:
1186 #ifdef HAVE_LIBJPEG
1187                 cinfo.err = jpeg_std_error (&jcerr);
1188                 jpeg_create_compress (&cinfo);
1189                 jpeg_mem_dest (&cinfo, &jpeg_dest, &jpeg_size);
1190                 cinfo.image_width = camera->pl->width;
1191                 cinfo.image_height = camera->pl->height;
1192                 cinfo.input_components = 3;
1193                 cinfo.in_color_space = JCS_RGB;
1194                 jpeg_set_defaults (&cinfo);
1195                 jpeg_start_compress (&cinfo, TRUE);
1196                 for (y = 0; y < cinfo.image_height; y++) {
1197                         for (x = 0; x < cinfo.image_width; x++) {
1198                                 int p = src[y][x];
1199                                 row[x * 3 + 0] = gdTrueColorGetRed(p);
1200                                 row[x * 3 + 1] = gdTrueColorGetGreen(p);
1201                                 row[x * 3 + 2] = gdTrueColorGetBlue(p);
1202                         }
1203                         jpeg_write_scanlines (&cinfo, row_pointer, 1);
1204                 }
1205                 jpeg_finish_compress (&cinfo);
1206                 jpeg_destroy_compress (&cinfo);
1207
1208                 if (jpeg_size > dest_size) {
1209                         free (jpeg_dest);
1210                         gp_log (GP_LOG_ERROR, "ax203",
1211                                 "JPEG is bigger then buffer");
1212                         return GP_ERROR_FIXED_LIMIT_EXCEEDED;
1213                 }
1214                 memcpy (dest, jpeg_dest, jpeg_size);
1215                 free (jpeg_dest);
1216                 /* Round size up to a multiple of 256 because of ax3003
1217                    abfs size granularity. */
1218                 return (jpeg_size + 0xff) & ~0xff;
1219 #else
1220                 return GP_ERROR_NOT_SUPPORTED;
1221 #endif
1222         }
1223         /* Never reached */
1224 #endif
1225         gp_log(GP_LOG_ERROR,"ax203", "GD decompression not supported - no libGD present during build");
1226         return GP_ERROR_NOT_SUPPORTED;
1227 }
1228
1229 static int
1230 ax203_defrag_memory(Camera *camera)
1231 {
1232         char **raw_pictures;
1233         struct ax203_fileinfo *fileinfo;
1234         int i, count, ret = GP_OK;
1235
1236         count = ax203_read_filecount (camera);
1237         if (count < 0) return count;
1238
1239         raw_pictures = calloc (count, sizeof (char *));
1240         fileinfo     = calloc (count, sizeof (struct ax203_fileinfo));
1241         if (!raw_pictures || !fileinfo) {
1242                 free (raw_pictures); free (fileinfo);
1243                 gp_log (GP_LOG_ERROR, "ax203", "allocating memory");
1244                 return GP_ERROR_NO_MEMORY;
1245         }
1246
1247         /* First read all pictures in raw format */
1248         for (i = 0; i < count; i++) {
1249                 ret = ax203_read_fileinfo (camera, i, &fileinfo[i]);
1250                 if (ret < 0) goto cleanup;
1251
1252                 if (!fileinfo[i].present)
1253                         continue;
1254
1255                 ret = ax203_read_raw_file(camera, i, &raw_pictures[i]);
1256                 if (ret < 0) goto cleanup;
1257         }
1258
1259         /* Delete all pictures from the frame */
1260         ret = ax203_delete_all (camera);
1261         if (ret < 0) goto cleanup;
1262         
1263         /* An last write them back (in one contineous block) */
1264         for (i = 0; i < count; i++) {
1265                 if (!fileinfo[i].present)
1266                         continue;
1267
1268                 ret = ax203_write_raw_file (camera, i, raw_pictures[i],
1269                                             fileinfo[i].size);
1270                 if (ret < 0) {
1271                         gp_log (GP_LOG_ERROR, "ax203",
1272                                 "AAI error writing back images during "
1273                                 "defragmentation some images will be lost!");
1274                         break;
1275                 }
1276         }
1277 cleanup:
1278         for (i = 0; i < count; i++)
1279                 free (raw_pictures[i]);
1280         free (raw_pictures);
1281         free (fileinfo);
1282
1283         return ret;
1284 }
1285
1286 int
1287 ax203_read_raw_file(Camera *camera, int idx, char **raw)
1288 {
1289         struct ax203_fileinfo fileinfo;
1290         int ret;
1291
1292         *raw = NULL;
1293
1294         CHECK (ax203_read_fileinfo (camera, idx, &fileinfo))
1295
1296         if (!fileinfo.present) {
1297                 gp_log (GP_LOG_ERROR, "ax203",
1298                         "trying to read a deleted file");
1299                 return GP_ERROR_BAD_PARAMETERS;
1300         }
1301
1302         /* Allocate 1 extra byte as tinyjpeg's huffman decoding sometimes
1303            reads a few bits more then it needs */
1304         *raw = malloc (fileinfo.size + 1);
1305         if (!*raw) {
1306                 gp_log (GP_LOG_ERROR, "ax203", "allocating memory");
1307                 return GP_ERROR_NO_MEMORY;
1308         }
1309
1310         ret = ax203_read_mem (camera, fileinfo.address, *raw, fileinfo.size);
1311         if (ret < 0) {
1312                 free (*raw);
1313                 *raw = NULL;
1314                 return ret;
1315         }
1316
1317         return fileinfo.size;
1318 }
1319
1320 int
1321 ax203_read_file(Camera *camera, int idx, int **rgb24)
1322 {
1323         int ret;
1324         char *src;
1325
1326         ret = ax203_read_raw_file (camera, idx, &src);
1327         if (ret < 0) return ret;
1328
1329         ret = ax203_decode_image (camera, src, ret + 1, rgb24);
1330         free(src);
1331
1332         return ret;
1333 }
1334
1335 /* ax203_write_file() helper functions */
1336
1337 /* The picture table in ABFS does not necessarily lists the pictures
1338    in the order they are stored in memory, but when looking for a hole
1339    in memory to store a new picture we need a list of used memory blocks
1340    in memory order. So we build one here. */
1341 static int
1342 ax203_fileinfo_cmp(const void *p1, const void *p2)
1343 {
1344         const struct ax203_fileinfo *f1 = p1;
1345         const struct ax203_fileinfo *f2 = p2;
1346         return f1->address - f2->address;
1347 }
1348
1349 static int
1350 ax203_build_used_mem_table(Camera *camera, struct ax203_fileinfo *table)
1351 {
1352         int i, count, found = 0;
1353         struct ax203_fileinfo fileinfo;
1354
1355         count = ax203_read_filecount (camera);
1356         if (count < 0) return count;
1357
1358         /* The beginning of the memory is used by the CD image and stuff */
1359         fileinfo.address = 0;
1360         switch (camera->pl->frame_version) {
1361         case AX203_FIRMWARE_3_3_x:
1362         case AX203_FIRMWARE_3_4_x:
1363                 fileinfo.size = camera->pl->fs_start + AX203_PICTURE_OFFSET;
1364                 break;
1365         case AX206_FIRMWARE_3_5_x:
1366                 fileinfo.size = camera->pl->fs_start + AX206_PICTURE_OFFSET;
1367                 break;
1368         case AX3003_FIRMWARE_3_5_x:
1369                 fileinfo.size = camera->pl->fs_start + AX3003_PICTURE_OFFSET;
1370                 break;
1371         }
1372         fileinfo.present = 1;
1373         table[found++] = fileinfo;
1374
1375         for (i = 0; i < count; i++) {
1376                 CHECK (ax203_read_fileinfo (camera, i, &fileinfo))
1377                 if (!fileinfo.present)
1378                         continue;
1379                 table[found++] = fileinfo;
1380         }
1381         qsort (table, found, sizeof(struct ax203_fileinfo),
1382                ax203_fileinfo_cmp);
1383
1384         /* Add a last memory used region which starts at the end of memory
1385            the size does not matter as this is the last entry. */
1386         switch (camera->pl->frame_version) {
1387         case AX203_FIRMWARE_3_3_x:
1388         case AX203_FIRMWARE_3_4_x:
1389         case AX206_FIRMWARE_3_5_x:
1390                 fileinfo.address = camera->pl->mem_size;
1391                 break;
1392         case AX3003_FIRMWARE_3_5_x:
1393                 fileinfo.address = camera->pl->mem_size - AX3003_BL_SIZE;
1394                 break;
1395         }
1396
1397         fileinfo.size    = 0;
1398         fileinfo.present = 1;
1399         table[found++] = fileinfo;
1400
1401         return found;
1402 }
1403
1404 /* Find a free slot in the ABFS table to store the fileinfo */
1405 static int
1406 ax203_find_free_abfs_slot(Camera *camera)
1407 {
1408         int i, max;
1409         struct ax203_fileinfo fileinfo;
1410
1411         max = ax203_max_filecount (camera);
1412         for (i = 0; i < max; i++) {
1413                 CHECK (ax203_read_fileinfo (camera, i, &fileinfo))
1414                 if (!fileinfo.present)
1415                         return i;
1416         }
1417
1418         gp_log (GP_LOG_ERROR, "ax203", "no free slot in ABFS ??");
1419         return GP_ERROR_NO_SPACE;
1420 }
1421
1422 int
1423 ax203_write_raw_file(Camera *camera, int idx, char *buf, int size)
1424 {
1425         struct ax203_fileinfo fileinfo;
1426         struct ax203_fileinfo used_mem[AX203_ABFS_SIZE / 2];
1427         int i, hole_size, used_mem_count, prev_end, free;
1428
1429 retry:
1430         used_mem_count = ax203_build_used_mem_table (camera, used_mem);
1431         if (used_mem_count < 0) return used_mem_count;
1432
1433         /* Try to find a large enough "hole" in the memory */
1434         for (i = 1, free = 0; i < used_mem_count; i++, free += hole_size) {
1435                 prev_end = used_mem[i - 1].address + used_mem[i - 1].size;
1436                 hole_size = used_mem[i].address - prev_end;
1437                 if (hole_size)
1438                         GP_DEBUG ("found a hole at: %08x, of %d bytes "
1439                                   "(need %d)\n", prev_end, hole_size, size);
1440                 if (hole_size >= size) {
1441                         /* bingo we have a large enough hole */
1442                         fileinfo.address = prev_end;
1443                         fileinfo.size    = size;
1444                         fileinfo.present = 1;
1445                         CHECK (ax203_write_fileinfo (camera, idx,
1446                                                      &fileinfo))
1447                         CHECK (ax203_update_filecount (camera))
1448                         CHECK (ax203_write_mem (camera, fileinfo.address,
1449                                                 buf, size))
1450                         return GP_OK;
1451                 }
1452         }
1453
1454         if (free >= size) {
1455                 gp_log (GP_LOG_DEBUG, "ax203",
1456                         "not enough contineous freespace to add file, "
1457                         "defragmenting memory");
1458                 CHECK (ax203_defrag_memory (camera))
1459                 goto retry;
1460         }
1461
1462         gp_log (GP_LOG_ERROR, "ax203", "not enough freespace to add file");
1463         return GP_ERROR_NO_SPACE;
1464 }
1465
1466 int
1467 ax203_write_file(Camera *camera, int **rgb24)
1468 {
1469         const int buf_size = camera->pl->width * camera->pl->height;
1470         char buf[buf_size];
1471         int size, abfs_slot;
1472
1473         size = ax203_encode_image (camera, rgb24, buf, buf_size);
1474         if (size < 0) return size;
1475
1476         abfs_slot = ax203_find_free_abfs_slot (camera);
1477         if (abfs_slot < 0) return abfs_slot;
1478
1479         CHECK (ax203_write_raw_file (camera, abfs_slot, buf, size))
1480
1481         return GP_OK;
1482 }
1483
1484 int
1485 ax203_delete_file(Camera *camera, int idx)
1486 {
1487         struct ax203_fileinfo fileinfo;
1488
1489         CHECK (ax203_read_fileinfo (camera, idx, &fileinfo))
1490
1491         if (!fileinfo.present) {
1492                 gp_log (GP_LOG_ERROR, "ax203",
1493                         "trying to delete an already deleted file");
1494                 return GP_ERROR_BAD_PARAMETERS;
1495         }
1496
1497         fileinfo.present = 0;
1498         CHECK (ax203_write_fileinfo (camera, idx, &fileinfo))
1499         CHECK (ax203_update_filecount (camera))
1500
1501         return GP_OK;
1502 }
1503
1504 int
1505 ax203_delete_all(Camera *camera)
1506 {
1507         char buf[AX203_ABFS_SIZE];
1508         int size, file0_offset = 0;
1509
1510         switch (camera->pl->frame_version) {
1511         case AX203_FIRMWARE_3_3_x:
1512         case AX203_FIRMWARE_3_4_x:
1513                 file0_offset = AX203_ABFS_FILE_OFFSET (0);
1514                 break;
1515         case AX206_FIRMWARE_3_5_x:
1516                 file0_offset = AX206_ABFS_FILE_OFFSET (0);
1517                 break;
1518         case AX3003_FIRMWARE_3_5_x:
1519                 file0_offset = AX3003_ABFS_FILE_OFFSET (0);
1520                 break;
1521         }
1522
1523         size = AX203_ABFS_SIZE - file0_offset;
1524         memset(buf, 0, size);
1525         CHECK (ax203_write_mem (camera, camera->pl->fs_start + file0_offset,
1526                                 buf, size))
1527         CHECK (ax203_update_filecount (camera))
1528
1529         return GP_OK;
1530 }
1531
1532 /* bss = block start sector */
1533 static int
1534 ax203_commit_block_4k(Camera *camera, int bss)
1535 {
1536         int block_sector_size = SPI_EEPROM_BLOCK_SIZE / SPI_EEPROM_SECTOR_SIZE;
1537         int i;
1538
1539         for (i = 0; i < block_sector_size; i++) {
1540                 if (!camera->pl->sector_dirty[bss + i])
1541                         continue;
1542
1543                 CHECK (ax203_erase4k_sector (camera, bss + i))
1544                 CHECK (ax203_write_sector (camera, bss + i,
1545                                            camera->pl->mem +
1546                                            (bss + i) *
1547                                            SPI_EEPROM_SECTOR_SIZE))
1548                 camera->pl->sector_dirty[bss + i] = 0;
1549         }
1550         return GP_OK;
1551 }
1552
1553 static int
1554 ax203_commit_block_64k(Camera *camera, int bss)
1555 {
1556         int block_sector_size = SPI_EEPROM_BLOCK_SIZE / SPI_EEPROM_SECTOR_SIZE;
1557         int i;
1558
1559         /* Make sure we have read the entire block before erasing it !! */
1560         for (i = 0; i < block_sector_size; i++)
1561                 CHECK (ax203_check_sector_present (camera, bss + i))
1562
1563         /* Erase the block */
1564         CHECK (ax203_erase64k_sector (camera, bss))
1565
1566         /* And re-program all sectors in the block */
1567         for (i = 0; i < block_sector_size; i++) {
1568                 CHECK (ax203_write_sector (camera, bss + i,
1569                                            camera->pl->mem +
1570                                            (bss + i) *
1571                                            SPI_EEPROM_SECTOR_SIZE))
1572                 camera->pl->sector_dirty[bss + i] = 0;
1573         }
1574         return GP_OK;
1575 }
1576
1577 static int
1578 ax203_commit_block_ax3003(Camera *camera, int bss)
1579 {
1580         int block_sector_size = SPI_EEPROM_BLOCK_SIZE / SPI_EEPROM_SECTOR_SIZE;
1581         int i, address = bss * SPI_EEPROM_SECTOR_SIZE;
1582
1583         /* Make sure we have read the entire block before erasing it !! */
1584         for (i = 0; i < block_sector_size; i++)
1585                 CHECK (ax203_check_sector_present (camera, bss + i))
1586
1587         if (!camera->pl->block_protection_removed) {
1588                 CHECK (ax203_eeprom_write_enable (camera))
1589                 CHECK (ax203_eeprom_clear_block_protection (camera))
1590                 CHECK (ax203_eeprom_wait_ready (camera))
1591                 camera->pl->block_protection_removed = 1;
1592         }
1593
1594         /* Erase the block */
1595         CHECK (ax203_erase64k_sector (camera, bss))
1596
1597         /* And program the block in one large 64k page write, the ax3003
1598            probably emulates this in firmware, to avoid usb bus overhead. */
1599         CHECK (ax203_eeprom_write_enable (camera))
1600         CHECK (ax203_eeprom_program_page (camera, address,
1601                                           camera->pl->mem + address,
1602                                           SPI_EEPROM_BLOCK_SIZE))
1603         CHECK (ax203_eeprom_wait_ready (camera))
1604
1605         for (i = 0; i < block_sector_size; i++)
1606                 camera->pl->sector_dirty[bss + i] = 0;
1607
1608         return GP_OK;
1609 }
1610
1611 int
1612 ax203_commit(Camera *camera)
1613 {
1614         int i, j;
1615         int mem_sector_size = camera->pl->mem_size / SPI_EEPROM_SECTOR_SIZE;
1616         int block_sector_size = SPI_EEPROM_BLOCK_SIZE / SPI_EEPROM_SECTOR_SIZE;
1617         int dirty_sectors;
1618
1619         /* We first check each 64k block for dirty sectors. If the block
1620            contains dirty sectors, decide wether to use 4k sector erase
1621            commands (if the eeprom supports it), or to erase and reprogram
1622            the entire block */
1623         for (i = 0; i < mem_sector_size; i += block_sector_size) {
1624                 dirty_sectors = 0;
1625                 for (j = 0; j < block_sector_size; j++)
1626                         if (camera->pl->sector_dirty[i + j])
1627                                 dirty_sectors++;
1628
1629                 /* If we have no dirty sectors in this block continue */
1630                 if (!dirty_sectors)
1631                         continue;
1632
1633                 if (camera->pl->frame_version == AX3003_FIRMWARE_3_5_x)
1634                         CHECK (ax203_commit_block_ax3003 (camera, i))
1635                 /* There are 16 4k sectors per 64k block, when we need to
1636                    program 12 or more sectors, programming the entire block
1637                    becomes faster */
1638                 else if (dirty_sectors < 12 && camera->pl->has_4k_sectors)
1639                         CHECK (ax203_commit_block_4k (camera, i))
1640                 else
1641                         CHECK (ax203_commit_block_64k (camera, i))
1642         }
1643         return GP_OK;
1644 }
1645
1646 static int
1647 ax203_init(Camera *camera)
1648 {
1649         GP_DEBUG ("ax203_init called");
1650
1651         camera->pl->mem = malloc(camera->pl->mem_size);
1652         if (!camera->pl->mem)
1653                 return GP_ERROR_NO_MEMORY;
1654
1655         CHECK (ax203_read_parameter_block (camera))
1656
1657         if ((camera->pl->width % 4) || (camera->pl->height % 4)) {
1658                 gp_log (GP_LOG_ERROR, "ax203",
1659                         "lcd width and height must be a multiple of 4");
1660                 return GP_ERROR_IO;
1661         }
1662
1663         return GP_OK;
1664 }
1665
1666 static void
1667 ax203_exit(Camera *camera)
1668 {
1669         if (camera->pl->jdec) {
1670                 tinyjpeg_free (camera->pl->jdec);
1671                 camera->pl->jdec = NULL;
1672         }
1673         free (camera->pl->mem);
1674         camera->pl->mem = NULL;
1675 }
1676
1677 int
1678 ax203_open_device(Camera *camera)
1679 {
1680         char buf[64];
1681         uint32_t id;
1682         int i;
1683
1684         CHECK (ax203_get_version (camera, buf))
1685         GP_DEBUG ("Appotech ax203 picframe firmware version: %s", buf);
1686
1687         /* Not sure if this is necessary, but the windows software does it */
1688         CHECK (ax203_eeprom_release_from_deep_powerdown (camera))
1689         CHECK (ax203_eeprom_device_identification (camera, buf))
1690         id = le32atoh((uint8_t *)buf);
1691         for (i = 0; ax203_eeprom_info[i].name; i++) {
1692                 if (ax203_eeprom_info[i].id == id)
1693                         break;
1694         }
1695         
1696         if (!ax203_eeprom_info[i].name) {
1697                 gp_log (GP_LOG_ERROR, "ax203", "unknown eeprom id: %08x", id);
1698                 return GP_ERROR_MODEL_NOT_FOUND;
1699         }
1700
1701         camera->pl->mem_size       = ax203_eeprom_info[i].mem_size;
1702         camera->pl->has_4k_sectors = ax203_eeprom_info[i].has_4k_sectors;
1703         GP_DEBUG ("%s EEPROM found, capacity: %d, has 4k sectors: %d",
1704                   ax203_eeprom_info[i].name, camera->pl->mem_size,
1705                   camera->pl->has_4k_sectors);
1706
1707         return ax203_init (camera);
1708 }
1709
1710 int
1711 ax203_open_dump(Camera *camera, const char *dump)
1712 {
1713         camera->pl->mem_dump = fopen(dump, "r+");
1714         if (!camera->pl->mem_dump) {
1715                 gp_log (GP_LOG_ERROR, "ax203", "opening memdump file: %s: %s",
1716                         dump, strerror(errno));
1717                 return GP_ERROR_IO_INIT;
1718         }
1719
1720         if (fseek (camera->pl->mem_dump, 0, SEEK_END)) {
1721                 gp_log (GP_LOG_ERROR, "ax203", "seeking memdump file: %s: %s",
1722                         dump, strerror(errno));
1723                 return GP_ERROR_IO_INIT;
1724         }
1725         camera->pl->mem_size = ftell (camera->pl->mem_dump);
1726         camera->pl->has_4k_sectors = 1;
1727
1728         return ax203_init (camera);
1729 }
1730
1731 void ax203_close(Camera *camera)
1732 {
1733         ax203_exit (camera);
1734         if (camera->pl->mem_dump) {
1735                 fclose (camera->pl->mem_dump);
1736                 camera->pl->mem_dump = NULL;
1737         }
1738 }
1739
1740 int
1741 ax203_get_mem_size(Camera *camera)
1742 {
1743         return camera->pl->mem_size;
1744 }
1745
1746 int
1747 ax203_get_free_mem_size(Camera *camera)
1748 {
1749         struct ax203_fileinfo used_mem[AX203_ABFS_SIZE / 2];
1750         int i, used_mem_count, prev_end, free = 0;
1751
1752         used_mem_count = ax203_build_used_mem_table (camera, used_mem);
1753         if (used_mem_count < 0) return used_mem_count;
1754
1755         /* Add the size of all holes in memory together */
1756         for (i = 1; i < used_mem_count; i++) {
1757                 prev_end = used_mem[i - 1].address + used_mem[i - 1].size;
1758                 free += used_mem[i].address - prev_end;
1759         }
1760
1761         return free;
1762 }