Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 11th February 2015, 11:08   #1  |  Link
pandy
Registered User
 
Join Date: Mar 2006
Posts: 1,038
Amiga HAM encoding and Avisynth.

Well - i was not sure where to start this thread...
Based on last discussion on making codecs and nostalgia for old, good video times, i started to think about Avisynth encoder (color script preprocessor) for HAM (HAM6 encoding).

Any ideas how/where to start? Color models (RGB vs ??)? etc...

Info:
HAM (Hold And Modify) is method to compress color video on Amiga family of computers - HAM can be considered as crude DPCM encoder for RGB images with fixed 2:1 compression ratio - 12 bits is stored on 6 bits. As very simplistic it suffer from some artifacts called "HAM fringe".

http://en.wikipedia.org/wiki/Hold-And-Modify

Have no clue in fact where to start - thanks for all comments.
pandy is offline   Reply With Quote
Old 11th February 2015, 13:28   #2  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 5,672
Hi Pandy.
Dont know if this is any good to you at all, but find zip: http://www.mediafire.com/download/yr...gaHamStuff.zip

With a few bits of C source + Motorola M68K assembler, written about 25 years ago.
IIRC it supports both HAM6 and HAM8 modes, there are probably some bits missing, I stripped out what I though might be most useful from
a reasonably large project.
Dealing with HAM is a bit of a PITA, I wish you good luck.

EDIT: There may be some parts that confuse, it was part of a project that ran on both ATARI ST and AMIGA and supports
some additionally weird ATARI stuff (Spectrum pics, think that was what they were called, or something like that).
There will also be mention of EHB, AMIGA Extra Half-Bright pics. The HAM register locking code provided was probably
not bettered anywhere for the Amiga.


EDIT: I remembered, Spectrum 512 and QPaint (EDIT: Or maybe it was Quantum Paint) were both supported weird ATARI formats.
Avoiding color fringing is a big problem, there is source in zip to count HAM edges, assists in choosing best register colors,
also good idea to find 'most spread out' colors in the color cube, ie darkest black, whitest white, redest red etc.
And I think that when modifiying (the M of HAM) the order is important, eg primarily G, then not sure if B or R next, think was actually
better with blue [EDIT: Wrong, see below assembler], might be mentioned in source (of course color distance, actual color to required color is important too).

No idea how you would go about writing a HAM pre-processor in Avisynth.
I'm dying to see what you can do with the truely awful HAM5 (EDIT: And HAM 7)

EDIT: Preamble to z4ham_lock(), assembler fn.
Code:
****************************************************************************
*   WARNING:- 7 plane HAM behaves like 5 plane !!!!
****************************************************************************
*                               z4ham_lock
*   Optimisations assume that LEAST frequently, ALL 3 RGB components are
*   different from the previous visible RGB. In this case, the greatest
*   RGB component (with preference in GRB order where EQUAL) is found and
*   is used as the modifier and the DELTA is computed from the sum of the
*   DELTA's of the other two components. The routine to find if there is a
*   register that provides a SMALLER (pref to modify if EQUAL) DELTA is
*   called and if found, then the current RGB is set from the register.
*   ELSE:- execution returns to modify the greatest RGB difference component.
*       Next least frequent is where two of the RGB components differ from
*   the previous visible RGB. In this case, the greater of the two differing
*   components is found and used as the modifying component and the DELTA
*   is computed for the other differing component. Similarly, the 'find a
*   nearer register' routine is called with similar result to above.
*       Next least frequent is where only 1 of the RGB components differ
*   from the previous visible RGB, in this case, the differing component
*   is used as the modifier for an EXACT color match to that required and
*   no attempt is made to look for a nearer register.
*       Assumed MOST frequently occurs the situation where all three RGB
*   components are identical to the previous visible RGB, in this case,
*   if the previous was set from a register then the same register index
*   is used as the pixel value. If it was a modifier then SCRAMBLING takes
*   place, if the previous modifier was R, then the G component is used as
*   the modifier, G goes to B and B goes to R. Scrambling is not necessary
*   but used so that it takes less time for s/ware to determine the color of
*   a HAM pixel at a later time.
*       The above assumptions can be made because the lesser frequent
*   conditions will converge on the more frequent conditions (thats how HAM
*   works at all).
*       A number of optimisations have been implemented. Firstly, the short
*   BCC (Branch on condition code) instructions are quicker (10 branch taken,
*   8 not taken) than the word sized branch instructions (10 branch taken, 
*   12 not taken). By juggling a bit, we have managed to keep all conditional
*   branches to short size and the algorhythm used takes the conditional 
*   branch's only for the less frequent conditions.
*       Modifying preference is given in the GRB order (G is the most
*   luminous color and B the least) where components are equal and because
*   of this slight preference, it is beneficial to assume that G is most
*   likely to be the same as the previous visible G, followed by R and then
*   B. The algorhythm takes this into account all throughout.
*       Where only 1 RGB component differs from previous, no attempt is made
*   to find a nearer register as a simple modify will produce the exact
*   color required.
*       Where 2 RGB components differ, we compare the difference to find the
*   greatest one rather than comparing their DELTA values. To do this we must
*   ensure that we have the absolute color difference (rather than a negative
*   ones), this saves time in not accessing 2 values from the DELTA table.
*       Where 3 RGB components differ, we compare the difference to find the
*   greatest one rather than comparing there DELTA values. To do this we must
*   ensure that we have the absolute color difference (rather than a negative
*   ones), this saves time in not accessing 3 values from the DELTA table. We
*   then use the sum of the 2 lesser DELTA's when looking for a nearer reg.
*       At ALL times during the main routine (excluding the find register
*   part), the 'G and B required color registers' maintain BYTE 1 (Hi byte
*   of word) to zero, tests and comparisons on the RGB differences are done
*   on bytes and must always be +ve when doing a difference comparison.
*   The 'R required color register' does not maintain hi byte to zero as
*   the read of the R RGB8 value is WORD sized, only when the DELTA value is
*   accessed from the table is the hi byte disgarded. (by transferring the R
*   byte into one of the by then obselete G/B regs with its hi byte cleared).
*   Accessing the DELTA table could be done using -ve values but by this time
*   the difference is always +ve unsigned byte.
*       The find nearer register routine MUST ensure that the hi bytes of
*   each 'G/B required color registers' are nullified on exit.
*       The find register routine uses the fact that the DELTA table is valid
*   for both +ve and -ve differences making considerable time savings.
*   Further optimization is done in finding a nearer register, what is
*   required is the register whose total DELTA from the required RGB is less
*   than the best so far found (if equal then ignore). To save keeping a
*   running total DELTA of the register being examined and having to do a
*   comparison on the accumulated total for each RGB delta, we instead preset
*   the running total with the value of the best so far and subtract each of
*   the R, G and B DELTA's where applicable which removes the need to do an
*   explicit comparison, we also insert a DBHI instruction after the subtract
*   which both acts as a conditional branch and if a better match is NOT
*   found and decrements the counter all in one go. The DBHI instruction
*   drops through only if a 'better match so far' (where the counter is not
*   decremented). Following the DBHI, it is necessary to have a BLS
*   instruction to detect whether or not the DBHI instr dropped through
*   because the counter ran out. This BLS instr is only executed when the
*   DBHI drops through (as it will do less frequently than looping) and
*   therefore saves considerable time in comparison with a BLS that branches
*   to a DBHI. If a better register is found than the current one, the
*   running DELTA register will actually contain the difference between the
*   current best and the new better match and we calculate the new DELTA
*   value by subtracting the running DELTA register from the best DELTA reg.
*
*       At the routine start, a copy of the CMAP is made on the stack WORD
*   sized for each R,G,B component and each value is left shifted by 1.
*   The find near register routine left shifts the required RGB values
*   and uses these left shifted R,G,B's to enable it to use the DELTA table
*   without making a WORD INDEX into it (ie the +ve, -ve difference is
*   already a word index). This saves an ADD.W instruction for delta table
*   accesses.
*   In addition, the R,G,B WORD SIZED OPTimized CMAP is split so that all
*   RED word are contiguous and ALL GRN WORDS are contiguous but offset
*   from its RED counterpart by (64*sizeof(UWORD)). BLU WORDS are similarly
*   offset from their RED counterpart by (2*(64*sizeof(UWORD))). 
*   This splitting of the cmap into words occupies a TOTAL of (3*64*2)
*   bytes of STACK space but enables accesses without clearing BYTE 1 of
*   each primary and also without making them a word sized index into the
*   delta table and the split mode access allows us to access the G and B
*   components with absolute offsets from the OPT CMAP RED pointer and
*   obviates the need to explicitly adjust the pointer to the next element
*   when a 'find better delta register' comparison fails as the fetch R
*   component and next element operation is performed in one go.
*   We anticipate that the 'find near reg' routine method will not be
*   bettered for speed !!!
*       Note, the '64' in the above calculations is the maximum number of
*   registers for a HAM8 bitmap.
****************************************************************************
*       We have adopted a SINGLE loop only for the HAM routines as there will
*   be little advantage in using a multiple (QUICK) method as used for the
*   REGISTER ROUTINES as the HAM routines already find the best HAM modify
*   delta prior to the find reg routine. Because the best HAM modify delta
*   has already narrowed down the delta, in the majority of cases a BEST
*   HAM reg will NOT be found and HAM modify will be used instead. The single
*   loop method does also have the advantage of not having an additional
*   10 clocks (DBCC) for each 16 registers and 10 clocks (DBCC) for the 1st
*   iteration when the num of registers is a multiple of 16 (the entry point
*   would be at the termination DBCC instruction). The multiple loop method
*   also needs further clocks for (MOVE.W 6(a7),Dx 12 clks : JMP x(pc,dx.w)
*   14 clks) to access the entry point of the routine.
*       When NO better match is found AT ALL (Not even for the RED componant
*   of any register) then the single loop method will actually be faster than
*   the multiple method as there will be no extra DBCC instruction for every
*   16 registers, the DBCC function is already processed at the same time as
*   the delta comparison with the DBHI instruction. The single loop method
*   also saves about 700 bytes.
*       The ONLY advantage of the multiple loop used by the REG routine is
*   achieved when an R,G,B component comparison yields a better delta where
*   BLS.S (branch not taken) only takes 8 clocks instead of 10 and does not
*   need the additional BLS.S instruction that the single loop routine needs
*   in such circumstances. Therefore for each R,G,B component better delta
*   match, the multiple loop method saves 24 clocks. (ie 3 * 24 if all 3 
*   R,G,B components provide a better match finding a BEST REG SO FAR).
****************************************************************************
*                               z4ham_lock
*   Syntax:-
*   void __regargs z4ham_lock(int w,int depth,UBYTE *o,RGB8 *CMAP,
*                       UWORD *DELTA8,RGB8 *rgb,int out_BPC,RGB8 mrgcol);
*   Can be called with NON-NATURAL RGB8 data with suitable NON-NATURAL CMAP
*   and DELTA table and the i/p BPC parm is used to convert (shift) the
*   modified levels to the true physical bitmap values. (ie CMAP index can be
*   used as is but when modifying R,G or B we may have to shift from eg 8 bpc
*   to eg 4 bpc).
*   The mrgcol parm is an RGB8 value with the TRUE bm index including any 
*   modifier in the 1st byte and the NON-NATURAL RGB values in bytes 1-3.
********
*       New method of finding which primary to modify by considering each
*   r,g,b byte as part of a binary table when set/unset eg:-
*       000     All same                                    1st Test
*       001     Blue only different
*       010     Green only different
*       011     Green and blue different
*       100     Red only different                          2nd Test
*       101     Red and bluedifferent
*       110     Red and green different
*       111     All different                               3rd Test
*   The current optical r,g,b is subtracted from the required r,g,b (as a
*   LONG) to find which primary components are different, if zero then all
*   are same. If greater than $00010101 then ALL are known to be different. 
*   Then other bytes are tested and cleared to find the differences.
*   
*   New HAM Method that copes better with finding best modifier (eg because
*   we need to take into acount the fact that HAM only has 4 or 6 bits of
*   precision in the modifiers.
*       1st compare with previously requested rgb to se if a repeated
*   duplicate search is un-necessary. (and futile if exact match was not
*   found on previous iteration).
*       2nd find optical R,G,B which are different from required R,G,B
*   (Required R,G,B != Current Optical R,G,B (LOKREG)).
*   If no difference then either scramble modifier or set same reg dependent
*   upon previous ix.
*       If 1 component differs then modify that component and  set the
*   SNAPPED (eg the Req 8 BPC component rounded to HAM modifier BPC (4 or 6)
*   and then convert back to 8 BPC again.
*       If 2 components differ then eg B same, R and G differ :-
*           Rdif=abs(LokregR-Rreq);
*           Gdif=abs(LokregG-Greq);
*           if(Rdif>Gdif)
*               {
*               NEW_MODIFIER_CODE = 1;      /* Modify Red (R=1,G=2,B=3) */
*               BEST_OPTICAL=SNAP[Rreq];
*               TotalDelta =    DeltaTab[Gdif] + 
*                               DeltaTab[Rreq-BEST_OPTICAL];
*               }               /* And the same for the alternate case */
********
*   Enter:-
*       D0.w    Pixel count (width)
*       D1.w    Depth
*       A0      O/P Buffer
*       A1      CMAP
*           Stack:-
*           0(sp).L     DELTA
*           4(sp).L     RGB8 *I/P Buffer
*           8(sp).L     O/P Bits per color
*           12(sp).L    RGB8 Entry color (4 Bytes, RGB)
*   Exit:-
*       D0-D1/A0-A1 Trashed
***************************************************************************
MRGDELT         EQU     0
MRGRGB          EQU     4
MRGBPC          EQU     8
MRGCOLOR        EQU     12
***************************************************************************
HREGSZ          EQU     (11*4)  
HOPTMAPSZ       EQU     (3*256*2)   
*****
HMODMSK         EQU     0               Natural position HAM Scramble modifiers
HLASTREGIX      EQU     4               Last but not necc Prev reg ix (not hamod)
HDTHRESH        EQU     6
HNREGS          EQU     8               Number of registers
HOPTMAP         EQU     10              Optimised CMAP
*****
HVARSZ          EQU     (HOPTMAP+HOPTMAPSZ) 
HARGOFF         EQU     (HVARSZ+HREGSZ+4)   ; Stak vars+reg store + ret addr
*****
HABMRGDELT      EQU     (HARGOFF+MRGDELT)
HABMRGRGB       EQU     (HARGOFF+MRGRGB)
HABMRGBPC       EQU     (HARGOFF+MRGBPC)
HABMRGCOLOR     EQU     (HARGOFF+MRGCOLOR)
***************************************************************************
@z4ham_lock:			movem.l	d2-d7/a2-a6,-(a7)
Beats the hell of out me what all that means
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 12th February 2015 at 08:19.
StainlessS is offline   Reply With Quote
Old 11th February 2015, 15:14   #3  |  Link
davidhorman
I'm the Doctor
 
Join Date: Jan 2004
Posts: 1,418
Quote:
Originally Posted by pandy View Post
Well - i was not sure where to start this thread...
Based on last discussion on making codecs and nostalgia for old, good video times, i started to think about Avisynth encoder
Encoder or decoder?

If you have some sample files, I'd be interested in having a go at it.

David
__________________
My AviSynth filters / I'm the Doctor
davidhorman is offline   Reply With Quote
Old 11th February 2015, 15:53   #4  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 5,672
David, here the only pic file I have access to, got about 3000, floppies, ATARI and AMIGA, cannot access the AMIGA ones.
No idea what the pic is, I think it might be a mountain (HAM8) http://www.mediafire.com/download/as...18wg0/FUJI.zip
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 11th February 2015, 17:21   #5  |  Link
johnmeyer
Registered User
 
Join Date: Feb 2002
Location: California
Posts: 1,987
Quote:
Originally Posted by StainlessS View Post
David, here the only pic file I have access to, got about 3000, floppies, ATARI and AMIGA, cannot access the AMIGA ones.
No idea what the pic is, I think it might be a mountain (HAM8) http://www.mediafire.com/download/as...18wg0/FUJI.zip
My old ACDSee viewer, which I still use every day on all my computers, views it just fine. It also can convert it. Here is a JPEG version. No mountain here:
johnmeyer is offline   Reply With Quote
Old 11th February 2015, 18:34   #6  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 5,672
Yes, no mountain, but just as insurmountable, I'm guessing.
Many thanx John, maybe i'll get my Amiga set up and try to locate some better examples.
Got some pics from a guy that paid $30,000 for a good stills camera, circa 1987.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 11th February 2015, 20:15   #7  |  Link
davidhorman
I'm the Doctor
 
Join Date: Jan 2004
Posts: 1,418
Aww, that's ruined my fun. I'd got as far as decoding the headers and was about to start decompressing...
__________________
My AviSynth filters / I'm the Doctor
davidhorman is offline   Reply With Quote
Old 11th February 2015, 21:13   #8  |  Link
pandy
Registered User
 
Join Date: Mar 2006
Posts: 1,038
Thank You Guys, few additional info's from my side,

Decoding HAM (6 or 8 or any other) is not a problem - HW is fully predictable, side to this ffmpeg support decoding.
Encoding is an issue - as Stainless pointed - there is at least few areas - edge detection as rapid change of color may need 2 pixels (fringe), color model (perhaps it is good to perform conversion in linear space not gamma?, perhaps different than RGB color space should be used and later mapped in RGB?, 16 color for CLUT not produce any distortions so their selection is crucial i assume).
So i think about Avisynth more like preprocessor than real encoder.

Two words on Atari ST (mentioned by Stainless).
Atari ST use different approach - Photochrome/Spectrum change color multiple time per 1 video line - this usually gives 48 different colors in 1 video line.
There is code with nice explanation:
http://www.leonik.net/dml/sec_pcs.py
And example how it works in case of video:
http://www.youtube.com/watch?v=w5EbCT0W_Ds
http://www.youtube.com/watch?v=urgixT_MPCU
Impressive!!!

Amiga may use similar tricks (but it may use specialized coprocessor "Copper" to perform such task instead CPU or it can use both - there is few video modes based on this principle such as SlicedHAM, Dynamic Hires, PCHG etc).

But for me interesting is plain HAM mode (so no dynamic color change) - for dynamic color change Amiga may use software from Atari ST (after porting).

HAM6 example (no color cycling)
http://www.youtube.com/watch?v=_7IYxjNaCd8
http://www.youtube.com/watch?v=TiPZdAdLtdg

There is some software for Amiga to convert RGB555 > HAM6 but i have impression that quality is suboptimal (conversion is very simple) that's why i have idea to use Avisynth as kind of preprocessing solution.

Btw im really impressed with overall high quality (better than VHS) offered by those mid 80's computers - not widely known fact is that probably one of first multimedia standards was created on Amiga (IFF - and it is still used today as RIFF/AIFF etc), CDXL was probably first video file format http://en.wikipedia.org/wiki/CDXL

Thanks once again.
pandy is offline   Reply With Quote
Old 12th February 2015, 08:00   #9  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 5,672
I have the Electronic Arts - Public Domain IFF Reader/Writer source code (full floppy) if anyone needs it (Amiga format floppy).

(IFF == Interchange File Format)

EDIT: Part of it is included in the previously given zip file (IFF.C).
EDIT: Provided source zip also includes some source for modified Floyd Steinberg error diffusion,
NOTE AMIGA HAM is unidirectional and so cannot use bi-directional Floyd.

Code:
/*
    AMIGA:-
        No direct access to AMIGA system libraries.
    NOTE QWIK ASM USED.
*/

/*  ------------------------------------------------------------------  */
/*                              !BREAK FLOYD.C                          */
/*  ------------------------------------------------------------------  */
/*                              RAS_diffuse_FS                          */
/*  Video dither with CLUT.(ie primary cols cannot be individually set) */
/*  and therefore errors must be WORD sized, where primary cols could   */
/*  be set individually, the maximum possible error is in the signed    */
/*  byte range.                                                         */
/*  Floyd diffuses error pattern :-                                     */
/*    X 7   Where X is the error and the diffusion denominator is in    */
/*  3 5 1   n/16ths of the error.                                       */
/*      We use a modified version of the above where we add in the      */
/*  errors from the previous raster rather than diffusing the error out */
/*  to the surrounding pixels, this is exactly the same in practice.    */
/*  This method uses the below table values to obtain the errors.       */
/*  1 5 3   Where Z is the required primary color value that has the    */
/*  7 Z     n/16ths of the error from the surrounding pixels added to   */
/*  it.                                                                 */
/*  NOTE, Found to produce best results of error additions in the       */
/*  natural order that would be processed if the non modified version   */
/*  is used ie in the order 1,5,3,7.                                    */
/*  NOTE, Experiments have so far shown that it is necessary to both    */
/*  calculate the n/16th part for every error addition and also to      */
/*  clamp to UBYTE range. Failure to do this results in artifacts.      */
/*  NOTE, HAM is unidirectional and therefore cannot use bidirectional  */
/*  error diffusion.                                                    */
/*      When dithering eg a full screen of mid grey (ie 0x80)           */
/*  FLOYD produces artifacts and so we have introduced a                */
/*  slight bias to the 1st raster pixel. We Bias with (2*(1/16)) of     */
/*  the above right pixel error to avoid artifacts produced by          */
/*  cumulative errors. This in effect pretends that the error from the  */
/*  ABOVE previous pixel (which is really out of range) is twice the    */
/*  error from the above right pixel. This is to EVEN OUT the errors    */
/*  so that not to great an emphasise is placed on the error from the   */
/*  above pixel and results in 5/16th's of the above pixel error and    */
/*  (3+2)/16th's (ie 5/16th's) of the above right pixel error.          */
/*  We have also found that this seems to produce better than           */
/*  bi-directional FLOYD so we will use this ONLY for now.              */
/*  ------------------------------------------------------------------  */
/*  Note, to divide a -ve number by 16 using a shift instruction it is  */
/*  necessary to 1st add 15 to it so that the result rounds towards     */
/*  zero. To both remove the need to detect whether a number is -ve and */
/*  to round both +ve and numbers to the nearest integer we will        */
/*  instead add 8 and then use ASR. This gives a slight error for -ve   */
/*  numbers, (to get the same result for +ve and -ve numbers we should  */
/*  really add 8 to +ve numbers and 7 to -ve numbers).                  */
/*  ------------------------------------------------------------------  */

#define DIFSMAC(a,b)    if((n+=((WORD)(((a)*(b))+(WORD)8)>>4))<0) \
                            n=0;else if(n>255)n=255;

void    RAS_diffuse_FS(bmix,rgb,cmap,deltatab,cmerr,vm,depth,hamlok,direc,w,rout)
BMIX    *bmix;
RGB8    *rgb,*cmap;
UWORD   *deltatab;
CM_ERR  *cmerr;
int     depth;
ULONG   vm;
RGB8    hamlok;
int     (*rout)(CMLOK*);
int     direc,w;
{
UWORD   optmap[3][256];
CM_ERR  *nxterr;
int     ix,n;
WORD    Ucarry[3],carry[3];
CMLOK   cm;                         /*  WARNING QUIK ASM CODE USED !!!! */
    cm.ipdepth=depth;cm.ipvm=vm;cm.ipbpc=8;
    cm.iplok=hamlok;cm.ipcmap=cmap;
    cm.ipoptmap=&optmap[0][0];
    cm.ipdelta8=deltatab;
    cm.xpos=0;cm.xinc=1;
#ifdef  BIDIRECTIONAL
    if(vm&HAM)direc=0;                      /* HAM is unidirectional */

    if(direc&0x01)
        {
        bmix+=w-1;cmerr+=w-1;rgb+=w-1;nxterr=cmerr-1;
        cm.xpos=w-1;
        cm.xinc=-1;
        }
    else
#endif
        {
        nxterr=cmerr+1;
        }
    if(!rout(&cm))return;
    carry[0]=carry[1]=carry[2]=0;
                        /* BIAS 1st PREV pixel error to reduce artifacts */
    Ucarry[0]=nxterr[0].col.r*2;
    Ucarry[1]=nxterr[0].col.g*2;
    Ucarry[2]=nxterr[0].col.b*2;
    for(;--w>=0;)
        {
        for(ix=3;--ix>=0;)
            {
            n=rgb->ix[ix+1];
            DIFSMAC(1,Ucarry[ix])
        /* Rem Next ABOVE PREV (as we overwrite with current pixel error) */
            DIFSMAC(5,(Ucarry[ix]=cmerr[0].ix[ix]))
            if(w)
                {
                DIFSMAC(3,nxterr[0].ix[ix])
                }
            DIFSMAC(7,carry[ix])
            cm.reqrgb[ix]=n;
            }
        *bmix=cm.rout(&cm);
        cmerr[0].col.r=carry[0]=cm.reqrgb[0]-cm.lokreg[0];
        cmerr[0].col.g=carry[1]=cm.reqrgb[1]-cm.lokreg[1];
        cmerr[0].col.b=carry[2]=cm.reqrgb[2]-cm.lokreg[2];
        cmerr=nxterr;
        #ifdef  BIDIRECTIONAL
            if(direc&0x01)
                {bmix--;nxterr--;rgb--;}
            else
        #endif
                {bmix++;nxterr++;rgb++;}
        }
}
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 12th February 2015 at 08:51.
StainlessS is offline   Reply With Quote
Old 12th February 2015, 10:26   #10  |  Link
pandy
Registered User
 
Join Date: Mar 2006
Posts: 1,038
Quote:
Originally Posted by StainlessS View Post

NOTE AMIGA HAM is unidirectional and so cannot use bi-directional Floyd.
Thx Stainless - this is my point - for video different dithering than FS is advised, also seem that FS is suboptimal from HAM perspective (my naive way of thinking lead me to conclusion that vertically biased aggressive dither can be better choice).
Why i think about some preprocessing (Avisynth? Vapoursynth?)? I want to use antialiasing (crucial for 320 pixels in line resolution), temporal smoothing (crucial for simplistic delta compression) etc.
pandy is offline   Reply With Quote
Old 12th February 2015, 11:04   #11  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 5,672
So far as I remember, Floyd unidirectional worked just fine with HAM, and as noted above works better than the usual bi-directional (with the noted mod).
EDIT: As long as the HAM register locking code is good. (Many commercial apps were really quite bad at register locking HAM)

Quote:
/* We have also found that this seems to produce better than */
/* bi-directional FLOYD so we will use this ONLY for now. */
EDIT: I thought that my AMIGA 1200 with 10MB of ram was a bit overkill (only 12MB possible if additional 2MB added to
PCMCIA adapter as either RAM or RAM disk), but you can get 128MB RAM upgrade now for it. Also thinking about a
4GB Compact flash drive [with IDE Adapter] for about 20.0)
Video: Amiga Upgrades :- https://www.youtube.com/watch?v=OIWS6D7pbb4
And search 'AmigaKit' on Google for your local AmigaKit store.
Managed to cap the YouTube clip above with Firefox & VideoCacheView (NirSoft) and GPac.

WOW!, just looked at the ST movie linked, never seen anything like that on ST before. (although I nearly always used
with the ATARI Hi-Res monitor [640x400 Black & white pixels only - no greyscale, like the original Mac but a bit higher rez]).
The mentioned QPaint (or was it Quantum Paint) also produced 4096 colors on ATARI STE, like Photochrome.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 14th February 2015 at 10:29.
StainlessS is offline   Reply With Quote
Old 16th February 2015, 10:41   #12  |  Link
pandy
Registered User
 
Join Date: Mar 2006
Posts: 1,038
Quote:
Originally Posted by StainlessS View Post
So far as I remember, Floyd unidirectional worked just fine with HAM, and as noted above works better than the usual bi-directional (with the noted mod).
EDIT: As long as the HAM register locking code is good. (Many commercial apps were really quite bad at register locking HAM)
Well dither in HAM is tricky part - my impression is that Bayer work better than FS, in HAM8 player some special proprietary "Storm" dither was used. Not sure on arithmetic dither http://pippin.gimp.org/a_dither/

16 color CLUT seem to be most important factor to reduce error, i saw (and also prepared) some "universal" CLUT that may be used efficiently.

Quote:
Originally Posted by StainlessS View Post
EDIT: I thought that my AMIGA 1200 with 10MB of ram was a bit overkill (only 12MB possible if additional 2MB added to
PCMCIA adapter as either RAM or RAM disk), but you can get 128MB RAM upgrade now for it. Also thinking about a
4GB Compact flash drive [with IDE Adapter] for about 20.0)
Video: Amiga Upgrades :- https://www.youtube.com/watch?v=OIWS6D7pbb4
And search 'AmigaKit' on Google for your local AmigaKit store.
Managed to cap the YouTube clip above with Firefox & VideoCacheView (NirSoft) and GPac.
Seem that there something better - still in development but very promising at this moment FPGA MC68k implementation faster than 68060 - hope it will be available soon.


Quote:
Originally Posted by StainlessS View Post
WOW!, just looked at the ST movie linked, never seen anything like that on ST before. (although I nearly always used
with the ATARI Hi-Res monitor [640x400 Black & white pixels only - no greyscale, like the original Mac but a bit higher rez]).
The mentioned QPaint (or was it Quantum Paint) also produced 4096 colors on ATARI STE, like Photochrome.
Yes, this is impressive - also there is source code for converter.
pandy is offline   Reply With Quote
Old 23rd February 2015, 08:30   #13  |  Link
jmac698
Registered User
 
Join Date: Jan 2006
Posts: 1,860
Ha.. C64 had FLI mode before any of that
https://www.youtube.com/watch?v=QATUjaFYbJ4

It's a trick to trigger a DMA fetch of colour memories on every line, improving colour resolution 8x vertically. That's 2 free colours per 4x1, 1 per 160x1 (actually 148), and 1 per 4x8.

I found an algorithmic solution for perfect FLI colouring.

IFLI is flickering between different FLI screens, it's like a temportal dither, you can blend two colours this way to make 136 or so.

Also write an IFF encoder for my commercial product that saved samples from RAM.

Sliced HAM looks virtually perfect.
jmac698 is offline   Reply With Quote
Old 23rd February 2015, 15:10   #14  |  Link
pandy
Registered User
 
Join Date: Mar 2006
Posts: 1,038
New FFmpeg adding :

Quote:
9.68 palettegen
9.69 paletteuse
And it works relatively good - some movie optimized CLUT can be generated (up to 256 colors) and later used - animated gif quality is significantly improved, this can be beneficial for Amiga too - 16 color LUT with HAM probably will be sufficient but still - question about video preprocessing is valid.
pandy is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 07:43.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2018, vBulletin Solutions Inc.