def embed_or_extract(algorithm, filename, destfilename, message, para, embed):
    """This function gets as parameters
    filename ... the input file name
    destfilename ... the output filen ame
    message ... the message
    para ... the parameter for the chosen algorithm
    embed ... boolean: if True, we embed, else we extract.
    If embed is True it uses libstego to embed the given message
    in the given output file, calling the <algorithm>_embed()
    function in libstego.
    If embed is False, it uses libstego to extract a message
    from the given file, calling the <algorithm>_extract()
    function in libstego.
    This function can therefor be called recursively to check
    if embedding a message worked by calling it with embed=False.
    """
    ending = filename[-3:]
    print ending
    if embed:
        msglen = len(message) + 1
    else:
        message = libstego.new_charp()
        msglen = libstego.new_intp()
    if ending == "gif":
        src_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()
        libstegofile.io_gif_read(filename, src_data, gif_int)
        if algorithm == "Sort / Unsort":
            if embed:
                libstego.sortunsort_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.sortunsort_extract(src_data, message, msglen, para)
        elif algorithm == "GifShuffle":
            if embed:
                if para.method == 1:
                    pw_message = para.password
                    pw_message_len = para.pwlen
                    para.password = ""
                    para.pwlen = 0
                    pwmsg_data = libstegofile.palette_data_t()
                    para.method = 0
                    libstego.gifshuffle_embed(src_data, pwmsg_data, pw_message, pw_message_len, para)
                    para.method = 1
                    libstego.gifshuffle_embed(pwmsg_data, stego_data, message, msglen, para)
                else:
                    print "normal gifshuffle:"
                    print "pw: " + para.password
                    print "pwlen: " + str(para.pwlen)
                    libstego.gifshuffle_embed(src_data, stego_data, message, msglen, para)
            else:
                if para.method == 1:
                    pw_message = para.password
                    pw_message_len = para.pwlen
                    para.password = ""
                    para.pwlen = 0
                    pwmsg_data = libstegofile.palette_data_t()
                    para.method = 0
                    libstego.gifshuffle_embed(src_data, pwmsg_data, pw_message, pw_message_len, para)
                    para.adv_pal = pwmsg_data
                    para.method = 1
                    libstego.gifshuffle_extract(src_data, message, msglen, para)
                else:
                    libstego.gifshuffle_extract(src_data, message, msglen, para)

        elif algorithm == "Frirui":
            if embed:
                libstego.frirui_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.frirui_extract(src_data, message, msglen, para)
        if embed:
            print "integrate and write ..."
            libstegofile.io_gif_integrate(gif_int, stego_data)
            libstegofile.io_gif_write(destfilename, gif_int)
        # libstegofile.io_gif_cleanup_data(stego_data)
        # libstegofile.io_gif_cleanup_data(src_data)
        # libstegofile.io_gif_cleanup_internal(gif_int)
    elif ending == "png":
        src_data = libstegofile.rgb_data_t()
        stego_data = libstegofile.rgb_data_t()
        png_int = libstegofile.png_internal_data_t()
        libstegofile.io_png_read(filename, src_data, png_int)
        if algorithm == "Battlesteg":
            if embed:
                libstego.battlesteg_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.battlesteg_extract(src_data, message, msglen, para)

        elif algorithm == "CPT":
            if embed:
                libstego.cpt_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.cpt_extract(src_data, message, msglen, para)

        elif algorithm == "LSB":
            bytes = libstego.new_charpp()
            num_bytes = libstego.new_intp()
            stego_data = src_data
            libstego.lsb_convert_png(stego_data, bytes, num_bytes)
            if embed:
                ret = libstego.lsb_embed_indirect(
                    libstego.charpp_value(bytes), libstego.intp_value(num_bytes), message, msglen, para
                )
                if ret != 0:
                    print "An error occured. Error code: " + ` libstego.cvar.lstg_errno `
                    return False
            else:
                ret = libstego.lsb_extract_indirect(
                    libstego.charpp_value(bytes), libstego.intp_value(num_bytes), message, msglen, para
                )
                if ret != 0:
                    print "An error occured. Error code: " + ` libstego.cvar.lstg_errno `
                    return False

            libstego.lsb_cleanup_converted_data(libstego.charpp_value(bytes))
            libstego.delete_charpp(bytes)

        if embed:
            libstegofile.io_png_integrate(png_int, stego_data)
            libstegofile.io_png_write(destfilename, png_int)
            libstegofile.io_png_cleanup_data(stego_data)
        # png cleanup ruft segmentation faults hervor...
        # libstegofile.io_png_cleanup_data(src_data)
        # libstegofile.io_png_cleanup_internal(png_int)

    elif ending == "svg":
        src_data = libstegofile.svg_data_t()
        stego_data = libstegofile.svg_data_t()
        svg_int = libstegofile.svg_internal_data_t()
        libstegofile.io_svg_read(filename, src_data, svg_int)
        if algorithm == "SVG Steg":
            if embed:
                ret = libstego.svg_embed(src_data, stego_data, message, msglen, para)

                if ret != 0:
                    print "An error occured. Error code: " + ` libstego.cvar.lstg_errno `
                    return False

            else:
                ret = libstego.svg_extract(src_data, message, msglen, para)

                if ret != 0:
                    print "An error occured. Error code: " + ` libstego.cvar.lstg_errno `
                    return False

        if embed:
            libstegofile.io_svg_integrate(svg_int, stego_data)
            libstegofile.io_svg_write(destfilename, svg_int)
            libstegofile.io_svg_cleanup_data(stego_data)

        libstegofile.io_svg_cleanup_data(src_data)
        libstegofile.io_svg_cleanup_internal(svg_int)

    elif ending == "wav":
        src_data = libstegofile.wav_data_t()
        stego_data = libstegofile.wav_data_t()
        wav_int = libstegofile.wav_internal_data_t()
        libstegofile.io_wav_read(filename, src_data, svg_int)
        if algorithm == "Echo Hiding":
            if embed:
                libstego.echohiding_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.echohiding_extract(src_data, message, msglen, para)
        elif algorithm == "Phase Coding":
            if embed:
                libstego.phasecoding_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.phasecoding_extract(src_data, message, msglen, para)
        libstegofile.io_wav_integrate(wav_int, stego_data)
        libstegofile.io_wav_write(destfilename, wav_int)
        libstegofile.io_wav_cleanup_data(stego_data)
        libstegofile.io_wav_cleanup_data(src_data)
        libstegofile.io_wav_cleanup_internal(wav_int)
    elif ending == "jpg" or "peg":
        src_data = libstegofile.jpeg_data_t()
        stego_data = libstegofile.jpeg_data_t()
        jpg_int = libstegofile.jpeg_internal_data_t()
        libstegofile.io_jpeg_read(filename, src_data, jpg_int)
        if algorithm == "F5":
            if embed:
                libstego.f5_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.f5_extract(src_data, message, msglen, para)
        elif algorithm == "MB2":
            if embed:
                libstego.mb2_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.mb2_extract(src_data, message, msglen, para)
        libstegofile.io_jpeg_integrate(jpg_int, stego_data)
        libstegofile.io_jpeg_write(destfilename, jpg_int)
        # libstegofile.io_jpeg_cleanup_data(stego_data)
        libstegofile.io_jpeg_cleanup_data(src_data)
        libstegofile.io_jpeg_cleanup_internal(jpg_int)
    # TODO: extract for testing purpose!
    if embed:
        return True
    else:
        new_message = str(libstego.charp_value(message))
        length = libstego.intp_value(msglen)
        print new_message
        return new_message
def embed_or_extract_with_method(embed, method, filename, destfilename, message, msglen):
    if embed:
        print "embedding with method " + `method+1` + ", algo: " + method_to_algo[method]
    else:
        p_message = libstego.new_charp()
        p_msglen = libstego.new_intp()
        print "extracting with method " + `method+1` + ", algo: " + method_to_algo[method]

    if method_to_algo[method] == "PQ":
        # prepare data strucures
        jpeg_data = libstegofile.jpeg_data_t()
        stego_data = libstegofile.jpeg_data_t()
        jpeg_int = libstegofile.jpeg_internal_data_t()

        # read file data
        err = libstegofile.io_jpeg_read(filename, jpeg_data, jpeg_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading JPG"
            return

        para = methods[method]
        if embed:
            err = libstego.pq_embed(jpeg_data, stego_data, message, len(message) + 1, para)
            if err == 0:
                err = libstegofile.io_jpeg_integrate(jpeg_int, stego_data)
                if err != 0:
                    print "Error while integrating JPEG"
                err = libstegofile.io_jpeg_write(destfilename, jpeg_int)
                if err != 0:
                    print "Error while writing JPEG"
            else:
                print "An error occured while embedding with PQ."
        else:
            err = libstego.pq_extract(jpeg_data, p_message, p_msglen, para)
            if err != 0:
                print "An error occured while extracting with PQ."

        # cleanup
        libstegofile.io_jpeg_cleanup_data(jpeg_data)
        libstegofile.io_jpeg_cleanup_data(stego_data)
        libstegofile.io_jpeg_cleanup_internal_data(jpeg_int)


    elif method_to_algo[method] == "F5":
        # prepare data strucures
        jpeg_data = libstegofile.jpeg_data_t()
        stego_data = libstegofile.jpeg_data_t()
        jpeg_int = libstegofile.jpeg_internal_data_t()

        # read file data
        err = libstegofile.io_jpeg_read(filename, jpeg_data, jpeg_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading JPG"
            return


        para = methods[method]
        if embed:
            err = libstego.f5_embed(jpeg_data, stego_data, message, len(message) + 1, para)
            if err == 0:
                err = libstegofile.io_jpeg_integrate(jpg_int, stego_data)
                err = libstegofile.io_jpeg_write(destfilename, jpeg_int)
            else:
                print "Error while embedding with F5."
        else:
            err = libstego.f5_extract(jpeg_data, p_message, p_msglen, para)
            if err != 0:
                print "Error while extracting with F5."

        # cleanup
        libstegofile.jpeg_cleanup_data(jpeg_data)
        libstegofile.io_jpeg_cleanup_data(stego_data)
        libstegofile.io_jpeg_cleanup_internal_data(jpeg_int)


    elif method_to_algo[method] == "Adv. Gifshuffle":
        # prepare data strucures
        palette_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()

        # read file data
        err = libstegofile.io_gif_read(filename, palette_data, gif_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading GIF"
            return

        para = methods[method]
        if embed:
            pw_message = para.password
            pw_message_len = para.pwlen
            para.password = ""
            para.pwlen = 0
            pwmsg_data = libstegofile.palette_data_t()
            para.method = 0
            err = libstego.gifshuffle_embed(palette_data, pwmsg_data, pw_message,
                    pw_message_len, para)
            para.method = 1
            err = libstego.gifshuffle_embed(pwmsg_data, stego_data,
                    message, msglen, para)

            err = libstegofile.io_gif_integrate(gif_int, stego_data)
            err = libstegofile.io_gif_write(destfilename, gif_int)
        else:
            pw_message = para.password
            pw_message_len = para.pwlen
            para.password = ""
            para.pwlen = 0
            pwmsg_data = libstegofile.palette_data_t()
            para.method = 0
            err = libstego.gifshuffle_embed(palette_data, pwmsg_data, pw_message,
                    pw_message_len, para)
            para.adv_pal = pwmsg_data
            para.method = 1
            err = libstego.gifshuffle_extract(palette_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_gif_cleanup_data(stego_data)
        libstegofile.io_gif_cleanup_data(palette_data)
        libstegofile.io_gif_cleanup_internal(gif_int)


    elif method_to_algo[method] == "Gifshuffle":
        # prepare data strucures
        palette_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()

        # read file data
        err = libstegofile.io_gif_read(filename, palette_data, gif_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading GIF"
            return

        para = methods[method]
        if embed:
            err = libstego.gifshuffle_embed(palette_data, stego_data, message, msglen, para)
            err = libstegofile.io_gif_integrate(gif_int, stego_data)
            err = libstegofile.io_gif_write(destfilename, gif_int)
        else:
            err = libstego.gifshuffle_extract(palette_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_gif_cleanup_data(stego_data)
        libstegofile.io_gif_cleanup_data(palette_data)
        libstegofile.io_gif_cleanup_internal(gif_int)


    elif method_to_algo[method] == "Frirui":
        # prepare data strucures
        palette_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()

        # read file data
        err = libstegofile.io_gif_read(filename, palette_data, gif_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading GIF"
            return

        para = methods[method]
        if embed:
            err = libstego.frirui_embed(palette_data, stego_data, message, msglen, para)

            err = libstegofile.io_gif_integrate(gif_int, stego_data)
            err = libstegofile.io_gif_write(destfilename, gif_int)
        else:
            err = libstego.frirui_extract(palette_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_gif_cleanup_data(stego_data)
        libstegofile.io_gif_cleanup_data(palette_data)
        libstegofile.io_gif_cleanup_internal(gif_int)


    elif method_to_algo[method] == "Sort/Unsort":
        # prepare data strucures
        palette_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()

        # read file data
        err = libstegofile.io_gif_read(filename, palette_data, gif_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading GIF"
            return

        para = methods[method]
        if embed:
            libstego.sortunsort_embed(palette_data, stego_data, message, msglen, para)

            err = libstegofile.io_gif_integrate(gif_int, stego_data)
            err = libstegofile.io_gif_write(destfilename, gif_int)
        else:
            libstego.sortunsort_extract(palette_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_gif_cleanup_data(stego_data)
        libstegofile.io_gif_cleanup_data(palette_data)
        libstegofile.io_gif_cleanup_internal(gif_int)

    elif method_to_algo[method] == "CPT":
        # prepare data strucures
        rgb_data = libstegofile.rgb_data_t()
        stego_data = libstegofile.rgb_data_t()
        png_int = libstegofile.png_internal_data_t()

        # read file data
        err = libstegofile.io_png_read(filename, rgb_data, png_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading PNG"
            return

        para = methods[method]
        if embed:
            print(para.password)
            print(para.pwlen)
            print(para.block_width)
            print(para.block_height)
            err = libstego.cpt_embed(rgb_data, stego_data, message, msglen, para)
            if err == 0:
                err = libstegofile.io_png_integrate(png_int, stego_data)
                err = libstegofile.io_png_write(destfilename, png_int)
        else:
            err = libstego.cpt_extract(rgb_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_png_cleanup_data(rgb_data)
        libstegofile.io_png_cleanup_data(stego_data)
        libstegofile.io_png_cleanup_internal(png_int)

    elif method_to_algo[method] == "Battlesteg":
        # prepare data strucures
        rgb_data = libstegofile.rgb_data_t()
        stego_data = libstegofile.rgb_data_t()
        png_int = libstegofile.png_internal_data_t()

        # read file data
        err = libstegofile.io_png_read(filename, rgb_data, png_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading PNG"
            return

        para = methods[method]
        if embed:
            err = libstego.battlesteg_embed(rgb_data, stego_data, message, msglen, para)
            if err == 0:
                err = libstegofile.io_png_integrate(png_int, stego_data)
                err = libstegofile.io_png_write(destfilename, png_int)
        else:
            err = libstego.battlesteg_extract(rgb_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_png_cleanup_data(rgb_data)
        libstegofile.io_png_cleanup_data(stego_data)
        libstegofile.io_png_cleanup_internal(png_int)


    elif method_to_algo[method] == "SVG Steg":
        # prepare data strucures
        svg_data = libstegofile.svg_data_t()
        svg_stego = libstegofile.svg_data_t()
        svg_int = libstegofile.svg_internal_data_t()

        # read file data
        err = libstegofile.io_svg_read(filename, svg_data, svg_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading SVG"
            return

        para = methods[method]
        if embed:
            err = libstego.svg_embed(svg_data, stego_data, message, msglen, para)
            if err == 0:
                err = libstegofile.io_svg_integrate(svg_int, stego_data)
                if err != 0:
                    print "Error while integrating SVG"
                err = libstegofile.io_svg_write(destfilename, svg_int)
                if err != 0:
                    print "Error while writing SVG"
            else:
                print "Error while embedding with SVG Stego"
        else:
            err = libstego.svg_extract(svg_data, p_message, p_msglen, para)
            if err != 0:
                print "Error while extracting with SVG Stego"

        # cleanup
        libstegofile.svg_cleanup_data(svg_data)
        libstegofile.svg_cleanup_data(stego_data)
        libstegofile.svg_cleanup_internal(svg_int)

    elif method_to_algo[method] == "Echo Hiding":
        # prepare data strucures
        wav_data = libstegofile.wav_data_t()
        stego_data = libstegofile.wav_data_t()
        wav_int = libstegofile.wav_internal_data_t()

        # read file data
        err = libstegofile.io_wav_read(filename, wav_data, wav_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading WAV"
            return

        para = methods[method]
        if embed:
            err = libstego.eh_embed(wav_data, stego_data, message, msglen, para)
            if err == 0:
                err = libstegofile.io_wav_integrate(wav_int, stego_data)
                if err != 0:
                    print "Error while integrating WAV"
                err = libstegofile.io_wav_write(destfilename, wav_int)
                if err != 0:
                    print "Error while writing WAV"
            else:
                print "Error while embedding with Echo Hiding"
        else:
            err = libstego.eh_extract(wav_data, p_message, p_msglen, para)
            if err != 0:
                print "Error while extracting with Echo Hiding"

        # cleanup
        libstegofile.wav_cleanup_data(wav_data)
        libstegofile.wav_cleanup_data(stego_data)
        libstegofile.wav_cleanup_internal(wav_int)


    elif method_to_algo[method] == "Phase Coding":
        # TODO implement
        pass


    elif method_to_algo[method] == "LSB":
        # TODO implement
        pass

    if embed:
        return None
    else:
        message = str(libstego.charp_value(p_message))
        print message
        msglen = libstego.intp_value(p_msglen)
        return message