Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / wodim / sector.c
1 /*
2  * This file has been modified for the cdrkit suite.
3  *
4  * The behaviour and appearence of the program code below can differ to a major
5  * extent from the version distributed by the original author(s).
6  *
7  * For details, see Changelog file distributed with the cdrkit package. If you
8  * received this file from another source then ask the distributing person for
9  * a log of modifications.
10  *
11  */
12
13 /* @(#)sector.c 1.13 04/03/01 Copyright 2001-2004 J. Schilling */
14 /*
15  *      Functions needed to use libedc_ecc from cdrecord
16  *
17  *      Copyright (c) 2001-2004 J. Schilling
18  */
19 /*
20  * This program is free software; you can redistribute it and/or modify
21  * it under the terms of the GNU General Public License version 2
22  * as published by the Free Software Foundation.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License along with
30  * this program; see the file COPYING.  If not, write to the Free Software
31  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32  */
33
34 #include <mconfig.h>
35 #include <stdio.h>
36 #include <standard.h>
37 #include <utypes.h>
38 #include <timedefs.h>
39 #include <schily.h>
40
41 #include "wodim.h"
42 #include "movesect.h"
43
44 #ifdef  HAVE_LIB_EDC_ECC
45
46
47 #define LAYER2
48 #define EDC_LAYER2
49 #define ENCODER
50 #define EDC_ENCODER
51 #include <ecc.h>
52
53 #ifdef  DO8
54 #define HAVE_NEW_LIB_EDC
55 #endif
56
57 int     encspeed(BOOL be_verbose);
58 void    encsectors(track_t *trackp, Uchar *bp, int address, int nsecs);
59 void    scrsectors(track_t *trackp, Uchar *bp, int address, int nsecs);
60 void    encodesector(Uchar *sp, int sectype, int address);
61 void    fillsector(Uchar *sp, int sectype, int address);
62
63 /*
64  * Sector types known by lib libedc_ecc:
65  */
66 #ifdef  __comment__
67                                 /*   MMC                                        */
68 #define MODE_0          0       /* -> XX  12+4+2336     (12+4uuu von libedc)    */
69 #define MODE_1          1       /* -> 8   12+4+2048+288 (124+4uuu+288 von libedc)*/
70 #define MODE_2          2       /* -> 9   12+4+2336     (12+4uuu von libedc)    */
71 #define MODE_2_FORM_1   3       /* -> 10/11 12+4+8+2048+280 (12+4hhhuuu+280 von libedc)*/
72 #define MODE_2_FORM_2   4       /* -> 12 (eher 13!) 12+4+8+2324+4 (12+4hhhuuu+4 von libedc)*/
73 #define AUDIO           5
74 #define UNKNOWN         6
75 #endif
76
77 /*
78  * known sector types
79  */
80 #ifndef EDC_MODE_0
81 #define EDC_MODE_0      MODE_0
82 #endif
83 #ifndef EDC_MODE_1
84 #define EDC_MODE_1      MODE_1
85 #endif
86 #ifndef EDC_MODE_2
87 #define EDC_MODE_2      MODE_2
88 #endif
89 #ifndef EDC_MODE_2_FORM_1
90 #define EDC_MODE_2_FORM_1       MODE_2_FORM_1
91 #endif
92 #ifndef EDC_MODE_2_FORM_2
93 #define EDC_MODE_2_FORM_2       MODE_2_FORM_2
94 #endif
95 #ifndef EDC_AUDIO
96 #define EDC_AUDIO       AUDIO
97 #endif
98 #ifndef EDC_UNKNOWN
99 #define EDC_UNKNOWN     UNKNOWN
100 #endif
101
102 /*
103  * Compute max sector encoding speed
104  */
105 int
106 encspeed(BOOL be_verbose)
107 {
108         track_t t[1];
109         Uchar   sect[2352];
110         int     i;
111         struct  timeval tv;
112         struct  timeval tv2;
113
114         t[0].sectype = ST_MODE_1;
115
116         /*
117          * Encoding speed is content dependant.
118          * Set up a known non-null pattern in the sector before; to make
119          * the result of this test independant of the current stack content.
120          */
121         for (i = 0; i < 2352; ) {
122                 sect[i++] = 'J';
123                 sect[i++] = 'S';
124         }
125         gettimeofday(&tv, (struct timezone *)0);
126         for (i = 0; i < 75000; i++) {           /* Goes up to 1000x */
127                 encsectors(t, sect, 12345, 1);
128                 gettimeofday(&tv2, (struct timezone *)0);
129                 if (tv2.tv_sec >= (tv.tv_sec+1) &&
130                     tv2.tv_usec >= tv.tv_usec)
131                         break;
132         }
133         if (be_verbose) {
134                 printf("Encoding speed : %dx (%d sectors/s) for libedc from Heiko Eißfeldt\n",
135                                 (i+74)/75, i);
136         }
137         return ((i+74)/75);
138 }
139
140 /*
141  * Encode sectors according to trackp->sectype
142  */
143 void
144 encsectors(track_t *trackp, Uchar *bp, int address, int nsecs)
145 {
146         int     sectype = trackp->sectype;
147
148         if ((sectype & ST_MODE_MASK) == ST_MODE_AUDIO)
149                 return;
150
151         while (--nsecs >= 0) {
152                 encodesector(bp, sectype, address);
153                 address++;
154                 bp += trackp->secsize;
155         }
156 }
157
158
159 #ifdef  CLONE_WRITE
160
161 #define IS_SECHDR(p)    ((p)[0] == 0 &&                         \
162                         (p)[1] == 0xFF && (p)[2] == 0xFF &&     \
163                         (p)[3] == 0xFF && (p)[4] == 0xFF &&     \
164                         (p)[5] == 0xFF && (p)[6] == 0xFF &&     \
165                         (p)[7] == 0xFF && (p)[8] == 0xFF &&     \
166                         (p)[9] == 0xFF && (p)[10] == 0xFF &&    \
167                         (p)[11] == 0)
168 /*
169  * Scramble data sectors without coding (needed for clone writing)
170  */
171 void
172 scrsectors(track_t *trackp, Uchar *bp, int address, int nsecs)
173 {
174         /*
175          * In Clone write mode, we cannot expect that the sector type
176          * of a "track" which really is a file holding the whole disk
177          * is flagged with something that makes sense.
178          *
179          * For this reason, we check each sector if it's a data sector
180          * and needs scrambling.
181          */
182         while (--nsecs >= 0) {
183                 if (IS_SECHDR(bp))
184                         scramble_L2(bp);
185                 bp += trackp->secsize;
186         }
187 }
188 #else
189 void
190 scrsectors(track_t *trackp, Uchar *bp, int address, int nsecs)
191 {
192         comerrno(EX_BAD, "Cannot write in clone RAW mode.\n");
193 }
194 #endif
195
196 /*
197  * Encode one sector according to trackp->sectype
198  */
199 void
200 encodesector(Uchar *sp, int sectype, int address)
201 {
202         if (address < -150)
203                 address += 450150;
204         else
205                 address += 150;
206 #define _address address
207
208
209         switch (sectype & ST_MODE_MASK) {
210
211         case    ST_MODE_0:
212                 do_encode_L2(sp, EDC_MODE_0, _address);
213                 break;
214
215         case    ST_MODE_1:
216                 do_encode_L2(sp, EDC_MODE_1, _address);
217                 break;
218
219         case    ST_MODE_2:
220                 do_encode_L2(sp, EDC_MODE_2, _address);
221                 break;
222
223         case    ST_MODE_2_FORM_1:
224                 sp[16+2]   &= ~0x20;    /* Form 1 sector */
225                 sp[16+4+2] &= ~0x20;    /* Form 1 sector 2nd copy */
226                 /* FALLTHROUGH */
227
228         case    ST_MODE_2_MIXED:
229                 do_encode_L2(sp, EDC_MODE_2_FORM_1, _address);
230                 break;
231
232         case    ST_MODE_2_FORM_2:
233                 sp[16+2]   |= 0x20;     /* Form 2 sector */
234                 sp[16+4+2] |= 0x20;     /* Form 2 sector 2nd copy */
235
236                 do_encode_L2(sp, EDC_MODE_2_FORM_2, _address);
237                 break;
238
239         case    ST_MODE_AUDIO:
240                 return;
241         default:
242                 fill2352(sp, '\0');
243                 return;
244         }
245         if ((sectype & ST_NOSCRAMBLE) == 0) {
246                 scramble_L2(sp);
247 #ifndef EDC_SCRAMBLE_NOSWAP
248                 swabbytes(sp, 2352);
249 #endif
250         }
251 }
252
253 /*
254  * Create one zero filles encoded sector (according to trackp->sectype)
255  */
256 void
257 fillsector(Uchar *sp, int sectype, int address)
258 {
259         fill2352(sp, '\0');
260         encodesector(sp, sectype, address);
261 }
262
263 #endif  /* HAVE_LIB_EDC_ECC */